use std::fmt::{Debug, Display, Formatter}; use std::{fmt, hash::Hasher}; use std::ops::Deref; use rkyv::{out_field, Archive, Deserialize, Serialize}; use serde::de::{Error, MapAccess, Unexpected}; use serde::ser::SerializeMap; use serde::Deserializer; use crate::resources::modules::fabaccess::OID_VALUE; use crate::MachineState; use crate::utils::oid::ObjectIdentifier; pub mod db; pub mod value; #[derive(Archive, Serialize, Deserialize, 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 fmt::Display for ArchivedState { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.inner, f) } } 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::value::*; use super::*; 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); } }