pub const MAX_MESSAGE_SIZE: usize = 256;
pub const MAX_LABEL_LEN: usize = 32;
pub const MAX_MESH_PEERS: usize = 16;
pub const MESH_TABLE_WASM_OFFSET: u32 = 0x24200;
#[derive(Clone, Copy)]
#[repr(C)]
pub struct MeshPeerEntry {
pub label: [u8; MAX_LABEL_LEN],
pub mesh_id: u64,
}
#[derive(Clone, Copy)]
#[repr(C)]
pub struct MeshTable {
pub self_label: [u8; MAX_LABEL_LEN],
pub self_mesh_id: u64,
pub peer_count: u8,
pub _pad: [u8; 7],
pub peers: [MeshPeerEntry; MAX_MESH_PEERS],
}
impl MeshPeerEntry {
pub const EMPTY: Self = Self {
label: [0; MAX_LABEL_LEN],
mesh_id: 0,
};
pub fn label_str(&self) -> &str {
let end = self.label.iter().position(|&b| b == 0).unwrap_or(MAX_LABEL_LEN);
core::str::from_utf8(&self.label[..end]).unwrap_or("")
}
}
impl MeshTable {
pub const EMPTY: Self = Self {
self_label: [0; MAX_LABEL_LEN],
self_mesh_id: 0,
peer_count: 0,
_pad: [0; 7],
peers: [MeshPeerEntry::EMPTY; MAX_MESH_PEERS],
};
pub fn self_label_str(&self) -> &str {
let end = self.self_label.iter().position(|&b| b == 0).unwrap_or(MAX_LABEL_LEN);
core::str::from_utf8(&self.self_label[..end]).unwrap_or("")
}
pub fn resolve(&self, label: &str) -> u64 {
let label_bytes = label.as_bytes();
for i in 0..self.peer_count as usize {
let entry = &self.peers[i];
let end = entry.label.iter().position(|&b| b == 0).unwrap_or(MAX_LABEL_LEN);
if end == label_bytes.len() && &entry.label[..end] == label_bytes {
return entry.mesh_id;
}
}
0
}
pub fn label_for(&self, mesh_id: u64) -> &str {
for i in 0..self.peer_count as usize {
if self.peers[i].mesh_id == mesh_id {
return self.peers[i].label_str();
}
}
""
}
}
#[cfg(target_arch = "wasm32")]
#[inline]
fn mesh_table() -> &'static MeshTable {
unsafe { &*(MESH_TABLE_WASM_OFFSET as *const MeshTable) }
}
#[cfg(target_arch = "wasm32")]
pub fn send(to: &str, payload: &[u8]) {
assert!(
payload.len() <= MAX_MESSAGE_SIZE,
"mesh message payload exceeds {} bytes",
MAX_MESSAGE_SIZE
);
let mesh_id = mesh_table().resolve(to);
if mesh_id != 0 {
unsafe {
__seq_send(mesh_id, payload.as_ptr() as u32, payload.len() as u32);
}
}
}
#[cfg(target_arch = "wasm32")]
extern "C" {
fn __seq_send(to: u64, ptr: u32, len: u32);
}
#[cfg(not(target_arch = "wasm32"))]
pub fn send(_to: &str, payload: &[u8]) {
assert!(
payload.len() <= MAX_MESSAGE_SIZE,
"mesh message payload exceeds {} bytes",
MAX_MESSAGE_SIZE
);
}
#[cfg(test)]
mod tests {
use super::*;
fn make_label(s: &str) -> [u8; MAX_LABEL_LEN] {
let mut l = [0u8; MAX_LABEL_LEN];
let b = s.as_bytes();
l[..b.len().min(MAX_LABEL_LEN)].copy_from_slice(&b[..b.len().min(MAX_LABEL_LEN)]);
l
}
fn make_table(self_label: &str, self_mesh_id: u64, peers: &[(&str, u64)]) -> MeshTable {
let mut t = MeshTable::EMPTY;
t.self_label = make_label(self_label);
t.self_mesh_id = self_mesh_id;
t.peer_count = peers.len() as u8;
for (i, &(label, id)) in peers.iter().enumerate() {
t.peers[i] = MeshPeerEntry {
label: make_label(label),
mesh_id: id,
};
}
t
}
#[test]
fn resolve_known_label() {
let t = make_table("self", 1, &[("maker", 10), ("hedger", 20)]);
assert_eq!(t.resolve("maker"), 10);
assert_eq!(t.resolve("hedger"), 20);
}
#[test]
fn resolve_unknown_returns_zero() {
let t = make_table("self", 1, &[("maker", 10), ("hedger", 20)]);
assert_eq!(t.resolve("scanner"), 0);
}
#[test]
fn resolve_empty_table() {
let t = make_table("self", 1, &[]);
assert_eq!(t.resolve("maker"), 0);
assert_eq!(t.resolve("anything"), 0);
}
#[test]
fn label_for_known_id() {
let t = make_table("self", 1, &[("maker", 10), ("hedger", 20)]);
assert_eq!(t.label_for(10), "maker");
assert_eq!(t.label_for(20), "hedger");
}
#[test]
fn label_for_unknown_returns_empty() {
let t = make_table("self", 1, &[("maker", 10)]);
assert_eq!(t.label_for(999), "");
}
#[test]
fn label_str_full_buffer() {
let entry = MeshPeerEntry {
label: [b'A'; MAX_LABEL_LEN],
mesh_id: 42,
};
let s = entry.label_str();
assert_eq!(s.len(), MAX_LABEL_LEN);
assert_eq!(s, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
}
#[test]
fn label_str_empty() {
let entry = MeshPeerEntry::EMPTY;
assert_eq!(entry.label_str(), "");
}
#[test]
fn label_str_normal() {
let entry = MeshPeerEntry {
label: make_label("hedger"),
mesh_id: 5,
};
assert_eq!(entry.label_str(), "hedger");
}
#[test]
fn self_label_str_works() {
let t = make_table("primary", 99, &[]);
assert_eq!(t.self_label_str(), "primary");
}
#[test]
fn round_trip() {
let t = make_table("self", 1, &[("maker", 10), ("hedger", 20), ("scanner", 30)]);
let id = t.resolve("hedger");
assert_eq!(id, 20);
let label = t.label_for(id);
assert_eq!(label, "hedger");
}
}