3个版本
0.1.2 | 2024年5月3日 |
---|---|
0.1.1 | 2024年5月3日 |
0.1.0 | 2024年5月3日 |
#448 在 编码
每月下载量33
81KB
1.5K SLoC
vestaboard-rs
vestaboard-rs
是一个针对 VBML (Vestaboard 标记语言) 的解析器和API客户端,用于 Vestaboard。它支持v2读写API、订阅API和本地API。
完整的文档可以在 https://docs.rs/vestaboard 找到
功能
- VBML解析器
- 读写API
- 订阅API
- 本地API
- Vestaboard消息的序列化和反序列化
- async/await
- 支持多个Vestaboard尺寸(如果有其他尺寸发布)
安装
cargo add vestaboard -F full
特性标志
full
:启用所有功能parser
:启用VBML解析器(Vestaboard标记语言)(默认)rw
:启用读写APIsubscription
:启用订阅APIlocal
:启用本地API
有用的类型和结构体
board::FLAGSHIP_ROWS
和board::FLAGSHIP_COLS
:旗舰Vestaboard的尺寸board::Board<ROWS, COLS>
:一个类型,等同于[[u8; COLS]; ROWS]
,表示Vestaboard的状态BoardData<ROWS, COLS>
:一个结构体,封装了一个Board<ROWS, COLS>
并具有几个辅助方法VBML
:一个表示VBML消息的结构体,可以解析为BoardData<ROWS, COLS>
Vestaboard<Config>
:用于与 Vestaboard API 交互的主要结构体
VBML 使用
指定 ROWS 和 COLS 时
let string = "{\"props\":{},\"style\":{},\"components\":[]}"; // any valid VBML string
let vbml: Vbml<6, 22> = string.parse().unwrap();
let board_data: Result<BoardData<6, 22>, VbmlError> = vbml.parse();
当未指定 ROWS 和 COLS 时,默认值为 board::FLAGSHIP_ROWS
和 board::FLAGSHIP_COLS
let string = "{\"props\":{},\"style\":{},\"components\":[]}"; // any valid VBML string
let vbml: Vbml = string.parse().unwrap();
let board_data: Result<BoardData, VbmlError> = vbml.parse();
API 使用
use vestaboard::{Vestaboard, RWConfig, SubscriptionConfig, LocalConfig};
#[tokio::main]
async fn main() {
let rw_config = RWConfig { read_write_key: "<YOUR_RW_API_KEY>" };
let rw_api: Vestaboard<RWConfig> = Vestaboard::new_rw_api(rw_config);
let subscription_config = SubscriptionConfig {
api_key: "<YOUR_SUBSCRIPTION_API_KEY>",
api_secret: "<YOUR_SUBSCRIPTION_API_SECRET>",
};
let subscription_api: Vestaboard<SubscriptionConfig> = Vestaboard::new_subscription_api(subscription_config);
let local_config = LocalConfig {
api_key: "<YOUR_LOCAL_API_KEY>",
host: "<YOUR_VESTABOARD_IP_ADDRESS>",
};
let local_api: Vestaboard<LocalConfig> = Vestaboard::new_local_api(local_config);
}
(请注意,由于 此 Rust 问题,您必须指定 Vestaboard<Config>
类型)
读写API
use vestaboard::{Vestaboard, RWConfig};
#[tokio::main]
async fn main() {
let rw_config = RWConfig { read_write_key: "<YOUR_RW_API_KEY>" };
let rw_api: Vestaboard<RWConfig> = Vestaboard::new_rw_api(rw_config);
let message: Result<RWApiReadMessage, RWApiError> = rw_api.read().await;
let write_res: Result<String, RWApiError> = rw_api.write(BoardData<ROWS, COLS>).await;
}
订阅API
use vestaboard::{Vestaboard, SubscriptionConfig};
#[tokio::main]
async fn main() {
let subscription_config = SubscriptionConfig {
api_key: "<YOUR_SUBSCRIPTION_API_KEY>",
api_secret: "<YOUR_SUBSCRIPTION_API_SECRET>",
};
let subscription_api: Vestaboard<SubscriptionConfig> = Vestaboard::new_subscription_api(subscription_config);
let subscriptions: Result<SubscriptionsList, SubscriptionApiError> = subscription_api.get_subscriptions().await;
let write_res: Result<SubscriptionMessageResponse, SubscriptionApiError> = subscription_api.write(BoardData<ROWS, COLS>).await;
}
本地API
use vestaboard::{Vestaboard, LocalConfig};
#[tokio::main]
async fn main() {
// if you have not enabled the local api, you can use the following method to do so.
// note that the local api can only be enabled once per board, so make sure to save
// the resulting api key. to get the enablement token, visit https://www.vestaboard.com/local-api
let local_api_enablement: Result<String, LocalApiError> = Vestaboard.get_local_api_key(
Some("<YOUR_VESTABOARD_IP_ADDRESS>".parse().unwrap()),
"<YOUR_LOCAL_API_ENABLEMENT_KEY>",
).await;
let local_config = LocalConfig {
api_key: "<YOUR_LOCAL_API_KEY>",
ip_address: "<YOUR_VESTABOARD_IP_ADDRESS>".parse().unwrap(),
};
let local_api: Vestaboard<LocalConfig> = Vestaboard::new_local_api(local_config);
let message: Result<BoardData<ROWS, COLS>, LocalApiError> = local_api.read().await;
let write_res: Result<(), LocalApiError> = local_api.write(BoardData<ROWS, COLS>).await;
}
基准测试
此库已配置为与官方 JavaScript VBML 解析库进行基准测试。可以使用 just 命令运行基准测试
just bench
在 Ryzen 9 7950X 的 Arch Linux 上,使用 Node v18.20.0 和 rustc 1.77.2,基准测试结果如下
测试名称 | js μs/it | rs μs/it | 差异 | 百分比更快 |
---|---|---|---|---|
默认模板 | 21.23μs | 0.40μs | -20.83μs | 5,338% |
半高居中 | 19.07μs | 0.40μs | -18.68μs | 4,792% |
左对齐 | 18.33μs | 0.39μs | -17.94μs | 4,669% |
右对齐 | 19.07μs | 0.39μs | -18.68μs | 4,838% |
居中对齐 | 21.23μs | 0.39μs | -20.84μs | 5,483% |
两端对齐 | 20.11μs | 0.39μs | -19.73μs | 5,192% |
居中对齐 | 21.43μs | 0.39μs | -21.05μs | 5,535% |
顶部对齐 | 18.98μs | 0.39μs | -18.58μs | 4,812% |
底部对齐 | 21.39μs | 0.39μs | -21.00μs | 5,511% |
两端对齐 | 21.36μs | 0.39μs | -20.97μs | 5,415% |
两端对齐且两端对齐 | 20.11μs | 0.38μs | -19.73μs | 5,277% |
分割对齐 | 24.49μs | 0.42μs | -24.08μs | 5,897% |
不均匀分割 | 23.85μs | 0.41μs | -23.43μs | 5,770% |
不均匀分割 2 | 21.64μs | 0.35μs | -21.29μs | 6,244% |
反转分割对齐 | 24.55μs | 0.42μs | -24.13μs | 5,850% |
两列 | 21.61μs | 0.35μs | -21.26μs | 6,153% |
全部两端对齐 | 27.32μs | 0.42μs | -26.90μs | 6,490% |
右对齐 | 15.76μs | 0.24μs | -15.51μs | 6,438% |
居中右对齐 | 15.69μs | 0.24μs | -15.45μs | 6,472% |
2x2x2x2 网格 | 37.68μs | 0.76μs | -36.91μs | 4,933% |
2x2 邻居 | 18.90μs | 0.37μs | -18.53μs | 5,046% |
纯文本 | 13.44μs | 0.24μs | -13.20μs | 5,564% |
居中 | 17.02μs | 0.24μs | -16.78μs | 7,055% |
换行 | 16.02μs | 0.26μs | -15.76μs | 6,230% |
字符编码 | 227.70μs | 17.94μs | -209.77μs | 1,270% |
带字符的字符编码 | 34.43μs | 1.52μs | -32.91μs | 2,269% |
动态属性 | 14.48μs | 0.65μs | -13.82μs | 2,223% |
带字符编码的动态属性 | 17.75μs | 1.13μs | -16.62μs | 1,571% |
多个组件 | 49.01μs | 2.34μs | -46.68μs | 2,099% |
原始字符 | 0.90μs | 0.04μs | -0.86μs | 2,126% |
绝对位置组件 | 24.33μs | 0.73μs | -23.60μs | 3,311% |
多个组件的复杂布局 | 70.41μs | 1.95μs | -68.46μs | 3,619% |
多个组件的复杂布局 2 | 76.98μs | 2.12μs | -74.86μs | 3,634% |
不同高度的组件换行 | 30.00μs | 0.60μs | -29.41μs | 5,028% |
JS 规范:绝对布局 | 18.19μs | 0.32μs | -17.87μs | 5,714% |
JS 规范:绝对布局 2 | 18.15μs | 0.32μs | -17.83μs | 5,704% |
JS 规范:绝对和原始组件 | 12.08μs | 0.48μs | -11.59μs | 2,496% |
肯定还有进一步优化的空间,但当前性能尚可。
依赖项
~4–16MB
~203K SLoC