Crates.io | vestaboard |
lib.rs | vestaboard |
version | 0.1.2 |
source | src |
created_at | 2024-05-03 03:22:28.505846 |
updated_at | 2024-05-03 03:51:12.315883 |
description | a wrapper for the Vestaboard API with support for v2 |
homepage | https://github.com/JoeyEamigh/vestaboard-rs |
repository | https://github.com/JoeyEamigh/vestaboard-rs.git |
max_upload_size | |
id | 1228340 |
size | 320,527 |
vestaboard-rs
is a VBML (Vestaboard Markup Language) parser and api client for the Vestaboard. It supports the v2 read/write api, subscription api, and local api.
the full docs can be found at https://docs.rs/vestaboard
cargo add vestaboard -F full
full
: enables all featuresparser
: enables the VBML parser (Vestaboard Markup Language) (default)rw
: enables the read/write apisubscription
: enables the subscription apilocal
: enables the local apiboard::FLAGSHIP_ROWS
and board::FLAGSHIP_COLS
: the dimensions of the flagship Vestaboardboard::Board<ROWS, COLS>
: a type equivalent to [[u8; COLS]; ROWS]
which represents a Vestaboard stateBoardData<ROWS, COLS>
: a struct that wraps a Board<ROWS, COLS>
and has several helper methodsVBML
: a struct that represents a VBML message and can be parsed into a BoardData<ROWS, COLS>
Vestaboard<Config>
: the main struct that is used to interact with the Vestaboard apiwith ROWS and COLS specified:
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();
when ROWS and COLS are not specified, the default is board::FLAGSHIP_ROWS
and 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();
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);
}
(note that you must have the Vestaboard<Config>
type specified due to this rust issue)
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;
}
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;
}
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;
}
this library is set up to be benchmarked against the official JavaScript VBML parsing library. benchmarks can be run using just with the following command:
just bench
on a Ryzen 9 7950X on Arch Linux with Node v18.20.0 and rustc 1.77.2, the benchmark results are as follows:
test name | js μs/it | rs μs/it | difference | % faster |
---|---|---|---|---|
Default Template | 21.23μs | 0.40μs | -20.83μs | 5,338% |
Half Height Center | 19.07μs | 0.40μs | -18.68μs | 4,792% |
Justify Left | 18.33μs | 0.39μs | -17.94μs | 4,669% |
Justify Right | 19.07μs | 0.39μs | -18.68μs | 4,838% |
Justify Center | 21.23μs | 0.39μs | -20.84μs | 5,483% |
Justify Justified | 20.11μs | 0.39μs | -19.73μs | 5,192% |
Align Center | 21.43μs | 0.39μs | -21.05μs | 5,535% |
Align Top | 18.98μs | 0.39μs | -18.58μs | 4,812% |
Align Bottom | 21.39μs | 0.39μs | -21.00μs | 5,511% |
Align Justified | 21.36μs | 0.39μs | -20.97μs | 5,415% |
Justify Justified Align Justified | 20.11μs | 0.38μs | -19.73μs | 5,277% |
Split Align Justify | 24.49μs | 0.42μs | -24.08μs | 5,897% |
Uneven Split | 23.85μs | 0.41μs | -23.43μs | 5,770% |
Uneven Split 2 | 21.64μs | 0.35μs | -21.29μs | 6,244% |
Rev Split Align Justify | 24.55μs | 0.42μs | -24.13μs | 5,850% |
Two Column | 21.61μs | 0.35μs | -21.26μs | 6,153% |
All Justified | 27.32μs | 0.42μs | -26.90μs | 6,490% |
Justified Right | 15.76μs | 0.24μs | -15.51μs | 6,438% |
Centered Right | 15.69μs | 0.24μs | -15.45μs | 6,472% |
2x2x2x2 Grid | 37.68μs | 0.76μs | -36.91μs | 4,933% |
2x2 Neighbors | 18.90μs | 0.37μs | -18.53μs | 5,046% |
Plain Text | 13.44μs | 0.24μs | -13.20μs | 5,564% |
Centered | 17.02μs | 0.24μs | -16.78μs | 7,055% |
Newline | 16.02μs | 0.26μs | -15.76μs | 6,230% |
Character Codes | 227.70μs | 17.94μs | -209.77μs | 1,270% |
Character Codes with Characters | 34.43μs | 1.52μs | -32.91μs | 2,269% |
Dynamic Props | 14.48μs | 0.65μs | -13.82μs | 2,223% |
Dynamic Props with Character Codes | 17.75μs | 1.13μs | -16.62μs | 1,571% |
Multiple Components | 49.01μs | 2.34μs | -46.68μs | 2,099% |
Raw Characters | 0.90μs | 0.04μs | -0.86μs | 2,126% |
Absolute Position Components | 24.33μs | 0.73μs | -23.60μs | 3,311% |
Complex Layout with Multiple Components | 70.41μs | 1.95μs | -68.46μs | 3,619% |
Complex Layout with Multiple Components 2 | 76.98μs | 2.12μs | -74.86μs | 3,634% |
Diff Height Components Newline | 30.00μs | 0.60μs | -29.41μs | 5,028% |
JS Spec: Absolute Layout | 18.19μs | 0.32μs | -17.87μs | 5,714% |
JS Spec: Absolute Layout 2 | 18.15μs | 0.32μs | -17.83μs | 5,704% |
JS Spec: Absolute and Raw Components | 12.08μs | 0.48μs | -11.59μs | 2,496% |
there is definitely further room for optimization, but the current performance is decent.