use std::{ fmt, hash::{ Hasher }, }; use std::fmt::Formatter; use std::ops::Deref; use rkyv::{ Archive, Deserialize, out_field, Serialize, }; use serde::de::{Error, MapAccess, Unexpected}; use serde::Deserializer; use serde::ser::SerializeMap; use crate::MachineState; use crate::resources::modules::fabaccess::OID_VALUE; use crate::utils::oid::ObjectIdentifier; pub mod value; pub mod db; #[derive(Archive, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq)] #[archive_attr(derive(Debug))] pub struct State { pub inner: MachineState, } impl fmt::Debug for State { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut sf = f.debug_struct("State"); //for Entry { oid, val } in self.inner.iter() { let k: String = OID_VALUE.deref().into(); sf.field(k.as_ref(), &self.inner); //} sf.finish() } } impl serde::Serialize for State { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { let mut ser = serializer.serialize_map(Some(1))?; ser.serialize_entry(OID_VALUE.deref(), &self.inner)?; ser.end() } } impl<'de> serde::Deserialize<'de> for State { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { deserializer.deserialize_map(StateVisitor) } } struct StateVisitor; impl<'de> serde::de::Visitor<'de> for StateVisitor { type Value = State; fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { write!(formatter, "a map from OIDs to value objects") } fn visit_map>(self, mut map: A) -> Result { let oid: ObjectIdentifier = map.next_key()? .ok_or(A::Error::missing_field("oid"))?; if oid != *OID_VALUE.deref() { return Err(A::Error::invalid_value(Unexpected::Other("Unknown OID"), &"OID of fabaccess state")) } let val: MachineState = map.next_value()?; Ok(State { inner: val }) } } #[cfg(test)] pub mod tests { use super::*; use super::value::*; pub(crate) fn gen_random() -> State { let amt: u8 = rand::random::() % 20; let mut sb = State::build(); for _ in 0..amt { let oid = crate::utils::oid::tests::gen_random(); sb = match rand::random::()%12 { 0 => sb.add(oid, Box::new(rand::random::())), 1 => sb.add(oid, Box::new(rand::random::())), 2 => sb.add(oid, Box::new(rand::random::())), 3 => sb.add(oid, Box::new(rand::random::())), 4 => sb.add(oid, Box::new(rand::random::())), 5 => sb.add(oid, Box::new(rand::random::())), 6 => sb.add(oid, Box::new(rand::random::())), 7 => sb.add(oid, Box::new(rand::random::())), 8 => sb.add(oid, Box::new(rand::random::())), 9 => sb.add(oid, Box::new(rand::random::())), 10 => sb.add(oid, Box::new(rand::random::())), 11 => sb.add(oid, Box::new(rand::random::())), _ => unreachable!(), } } sb.finish() } #[test] fn test_equal_state_is_eq() { let stateA = State::build() .add(OID_POWERED.clone(), Box::new(false)) .add(OID_INTENSITY.clone(), Box::new(1024)) .finish(); let stateB = State::build() .add(OID_POWERED.clone(), Box::new(false)) .add(OID_INTENSITY.clone(), Box::new(1024)) .finish(); assert_eq!(stateA, stateB); } #[test] fn test_unequal_state_is_ne() { let stateA = State::build() .add(OID_POWERED.clone(), Box::new(true)) .add(OID_INTENSITY.clone(), Box::new(512)) .finish(); let stateB = State::build() .add(OID_POWERED.clone(), Box::new(false)) .add(OID_INTENSITY.clone(), Box::new(1024)) .finish(); assert_ne!(stateA, stateB); } #[test] fn test_state_is_clone() { let stateA = gen_random(); let stateB = stateA.clone(); let stateC = stateB.clone(); drop(stateA); assert_eq!(stateC, stateB); } }