#![cfg_attr(not(feature = "wasm"), no_std)]
#[cfg(feature = "host")]
extern crate alloc;
pub mod action;
pub mod battery;
pub mod ble;
pub mod combo;
pub mod connection;
pub mod constants;
#[cfg(feature = "dfu")]
pub mod dfu;
pub mod fmt;
pub mod fork;
pub mod keycode;
pub mod led_indicator;
pub mod modifier;
pub mod morse;
pub mod mouse_button;
pub mod protocol;
#[cfg(feature = "steno")]
pub mod steno;
pub(crate) const fn varint_max_size(max_n: usize) -> usize {
const BITS_PER_BYTE: usize = 8;
const BITS_PER_VARINT_BYTE: usize = 7;
if max_n == 0 {
return 1;
}
let bits = core::mem::size_of::<usize>() * BITS_PER_BYTE - max_n.leading_zeros() as usize;
let roundup_bits = bits + (BITS_PER_VARINT_BYTE - 1);
roundup_bits / BITS_PER_VARINT_BYTE
}
pub(crate) const fn heapless_vec_max_size<T: postcard::experimental::max_size::MaxSize, const N: usize>() -> usize {
T::POSTCARD_MAX_SIZE * N + varint_max_size(N)
}
#[cfg(test)]
mod tests {
use heapless::Vec;
use super::{heapless_vec_max_size, varint_max_size};
#[test]
fn varint_max_size_matches_postcard() {
assert_eq!(varint_max_size(0), 1);
assert_eq!(varint_max_size(1), 1);
assert_eq!(varint_max_size(127), 1);
assert_eq!(varint_max_size(128), 2);
assert_eq!(varint_max_size(16383), 2);
assert_eq!(varint_max_size(16384), 3);
let mut buf = [0u8; 16];
for &n in &[0usize, 1, 127, 128, 255, 256, 16383, 16384, 65535] {
let bytes = postcard::to_slice(&n, &mut buf).unwrap();
assert!(
bytes.len() <= varint_max_size(n),
"varint_max_size({n}) = {} but postcard used {} bytes",
varint_max_size(n),
bytes.len()
);
}
}
#[test]
fn heapless_vec_max_size_matches_postcard() {
let mut v: Vec<u32, 8> = Vec::new();
for _ in 0..8 {
v.push(u32::MAX).unwrap();
}
let mut buf = [0u8; 64];
let bytes = postcard::to_slice(&v, &mut buf).unwrap();
assert_eq!(
bytes.len(),
heapless_vec_max_size::<u32, 8>(),
"tight bound: 8 × u32::MAX + varint(8)",
);
let empty: Vec<u32, 8> = Vec::new();
let bytes = postcard::to_slice(&empty, &mut buf).unwrap();
assert!(bytes.len() <= heapless_vec_max_size::<u32, 8>());
}
}