use serde::{Deserialize, Serialize};
use crate::{
schema::{DataModelType, NamedType},
Schema,
};
pub mod hash;
#[cfg(feature = "defmt-v0_3")]
use defmt_v0_3 as defmt;
#[cfg_attr(feature = "defmt-v0_3", derive(defmt_v0_3::Format))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize, Deserialize, Hash)]
pub struct Key([u8; 8]);
impl Schema for Key {
const SCHEMA: &'static crate::schema::NamedType = &NamedType {
name: "Key",
ty: &DataModelType::NewtypeStruct(<[u8; 8] as Schema>::SCHEMA),
};
}
impl core::fmt::Debug for Key {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("Key(")?;
for b in self.0.iter() {
f.write_fmt(format_args!("{b} "))?;
}
f.write_str(")")
}
}
impl Key {
pub const fn for_path<T>(path: &str) -> Self
where
T: Schema + ?Sized,
{
Key(hash::fnv1a64::hash_ty_path::<T>(path))
}
pub const unsafe fn from_bytes(bytes: [u8; 8]) -> Self {
Self(bytes)
}
pub const fn to_bytes(&self) -> [u8; 8] {
self.0
}
pub const fn const_cmp(&self, other: &Self) -> bool {
let mut i = 0;
while i < self.0.len() {
if self.0[i] != other.0[i] {
return false;
}
i += 1;
}
true
}
}
#[cfg(feature = "use-std")]
mod key_owned {
use super::*;
use crate::schema::owned::OwnedNamedType;
impl Key {
pub fn for_owned_schema_path(path: &str, nt: &OwnedNamedType) -> Key {
Key(hash::fnv1a64_owned::hash_ty_path_owned(path, nt))
}
}
}
#[cfg(test)]
mod test {
use crate::{
key::Key,
schema::{DataModelType, NamedType},
Schema,
};
#[test]
fn matches_old_postcard_rpc_defn() {
let old = &NamedType {
name: "Key",
ty: &DataModelType::NewtypeStruct(&NamedType {
name: "[T; N]",
ty: &DataModelType::Tuple(&[
&NamedType {
name: "u8",
ty: &DataModelType::U8,
},
&NamedType {
name: "u8",
ty: &DataModelType::U8,
},
&NamedType {
name: "u8",
ty: &DataModelType::U8,
},
&NamedType {
name: "u8",
ty: &DataModelType::U8,
},
&NamedType {
name: "u8",
ty: &DataModelType::U8,
},
&NamedType {
name: "u8",
ty: &DataModelType::U8,
},
&NamedType {
name: "u8",
ty: &DataModelType::U8,
},
&NamedType {
name: "u8",
ty: &DataModelType::U8,
},
]),
}),
};
let new = <Key as Schema>::SCHEMA;
assert_eq!(old, new);
}
}