#![cfg_attr(not(any(test, feature = "use-std")), no_std)]
#![deny(missing_docs)]
#![deny(unused_imports)]
#![deny(rustdoc::broken_intra_doc_links)]
#[doc(hidden)]
pub use postcard;
#[doc(hidden)]
pub use postcard_schema;
use header::{VarKey, VarKeyKind};
use postcard_schema::{schema::NamedType, Schema};
use serde::{Deserialize, Serialize};
pub mod header;
mod macros;
pub mod server;
pub mod standard_icd;
pub mod uniques;
#[cfg(feature = "cobs")]
pub mod accumulator;
#[cfg(feature = "use-std")]
pub mod host_client;
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils;
pub use postcard_schema::key::hash;
pub use postcard_schema::key::Key;
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Key1(u8);
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Key2([u8; 2]);
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Key4([u8; 4]);
impl Key1 {
#[inline]
pub const fn from_key2(value: Key2) -> Self {
let [a, b] = value.0;
Self(a ^ b)
}
#[inline]
pub const fn from_key4(value: Key4) -> Self {
let [a, b, c, d] = value.0;
Self(a ^ b ^ c ^ d)
}
#[inline]
pub const fn from_key8(value: Key) -> Self {
let [a, b, c, d, e, f, g, h] = value.to_bytes();
Self(a ^ b ^ c ^ d ^ e ^ f ^ g ^ h)
}
#[inline]
pub const fn to_bytes(&self) -> u8 {
self.0
}
#[inline]
pub fn try_from_varkey(value: &VarKey) -> Option<Self> {
Some(match value {
VarKey::Key1(key1) => *key1,
VarKey::Key2(key2) => Key1::from_key2(*key2),
VarKey::Key4(key4) => Key1::from_key4(*key4),
VarKey::Key8(key) => Key1::from_key8(*key),
})
}
}
impl Key2 {
#[inline]
pub const fn from_key4(value: Key4) -> Self {
let [a, b, c, d] = value.0;
Self([a ^ b, c ^ d])
}
#[inline]
pub const fn from_key8(value: Key) -> Self {
let [a, b, c, d, e, f, g, h] = value.to_bytes();
Self([a ^ b ^ c ^ d, e ^ f ^ g ^ h])
}
#[inline]
pub const fn to_bytes(&self) -> [u8; 2] {
self.0
}
#[inline]
pub fn try_from_varkey(value: &VarKey) -> Option<Self> {
Some(match value {
VarKey::Key1(_) => return None,
VarKey::Key2(key2) => *key2,
VarKey::Key4(key4) => Key2::from_key4(*key4),
VarKey::Key8(key) => Key2::from_key8(*key),
})
}
}
impl Key4 {
#[inline]
pub const fn from_key8(value: Key) -> Self {
let [a, b, c, d, e, f, g, h] = value.to_bytes();
Self([a ^ b, c ^ d, e ^ f, g ^ h])
}
#[inline]
pub const fn to_bytes(&self) -> [u8; 4] {
self.0
}
#[inline]
pub fn try_from_varkey(value: &VarKey) -> Option<Self> {
Some(match value {
VarKey::Key1(_) => return None,
VarKey::Key2(_) => return None,
VarKey::Key4(key4) => *key4,
VarKey::Key8(key) => Key4::from_key8(*key),
})
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct TooSmall;
impl TryFrom<&VarKey> for Key1 {
type Error = TooSmall;
#[inline]
fn try_from(value: &VarKey) -> Result<Self, Self::Error> {
Self::try_from_varkey(value).ok_or(TooSmall)
}
}
impl TryFrom<&VarKey> for Key2 {
type Error = TooSmall;
#[inline]
fn try_from(value: &VarKey) -> Result<Self, Self::Error> {
Self::try_from_varkey(value).ok_or(TooSmall)
}
}
impl TryFrom<&VarKey> for Key4 {
type Error = TooSmall;
#[inline]
fn try_from(value: &VarKey) -> Result<Self, Self::Error> {
Self::try_from_varkey(value).ok_or(TooSmall)
}
}
impl TryFrom<&VarKey> for Key {
type Error = TooSmall;
#[inline]
fn try_from(value: &VarKey) -> Result<Self, Self::Error> {
if let VarKey::Key8(key) = value {
Ok(*key)
} else {
Err(TooSmall)
}
}
}
impl From<Key2> for Key1 {
fn from(value: Key2) -> Self {
Self::from_key2(value)
}
}
impl From<Key4> for Key1 {
fn from(value: Key4) -> Self {
Self::from_key4(value)
}
}
impl From<Key> for Key1 {
fn from(value: Key) -> Self {
Self::from_key8(value)
}
}
impl From<Key4> for Key2 {
fn from(value: Key4) -> Self {
Self::from_key4(value)
}
}
impl From<Key> for Key2 {
fn from(value: Key) -> Self {
Self::from_key8(value)
}
}
impl From<Key> for Key4 {
fn from(value: Key) -> Self {
Self::from_key8(value)
}
}
pub trait Endpoint {
type Request: Schema;
type Response: Schema;
const PATH: &'static str;
const REQ_KEY: Key;
const REQ_KEY4: Key4 = Key4::from_key8(Self::REQ_KEY);
const REQ_KEY2: Key2 = Key2::from_key8(Self::REQ_KEY);
const REQ_KEY1: Key1 = Key1::from_key8(Self::REQ_KEY);
const RESP_KEY: Key;
const RESP_KEY4: Key4 = Key4::from_key8(Self::RESP_KEY);
const RESP_KEY2: Key2 = Key2::from_key8(Self::RESP_KEY);
const RESP_KEY1: Key1 = Key1::from_key8(Self::RESP_KEY);
}
pub trait Topic {
type Message: Schema + ?Sized;
const PATH: &'static str;
const TOPIC_KEY: Key;
const TOPIC_KEY4: Key4 = Key4::from_key8(Self::TOPIC_KEY);
const TOPIC_KEY2: Key2 = Key2::from_key8(Self::TOPIC_KEY);
const TOPIC_KEY1: Key1 = Key1::from_key8(Self::TOPIC_KEY);
}
#[derive(Debug, PartialEq, Clone, Copy, Schema, Serialize, Deserialize)]
pub enum TopicDirection {
ToServer,
ToClient,
}
pub struct DeviceMap {
pub types: &'static [&'static NamedType],
pub endpoints: &'static [(&'static str, Key, Key)],
pub topics_in: &'static [(&'static str, Key)],
pub topics_out: &'static [(&'static str, Key)],
pub min_key_len: VarKeyKind,
}
#[derive(Debug)]
pub struct EndpointMap {
pub types: &'static [&'static NamedType],
pub endpoints: &'static [(&'static str, Key, Key)],
}
#[derive(Debug)]
pub struct TopicMap {
pub direction: TopicDirection,
pub types: &'static [&'static NamedType],
pub topics: &'static [(&'static str, Key)],
}