#api-client #parser #markup-language #api #vbml

vestaboard

Vestaboard API的包装器,支持v2版本

3个版本

0.1.2 2024年5月3日
0.1.1 2024年5月3日
0.1.0 2024年5月3日

#448编码

每月下载量33

MIT 许可证

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:启用读写API
  • subscription:启用订阅API
  • local:启用本地API

有用的类型和结构体

  • board::FLAGSHIP_ROWSboard::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_ROWSboard::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