fabaccess-bffh/bffhd/resources/state/mod.rs

152 lines
4.4 KiB
Rust
Raw Normal View History

use std::{
fmt,
hash::{
Hasher
},
};
2022-03-16 18:10:59 +01:00
use std::fmt::{Debug, Display, Formatter};
use std::marker::PhantomData;
2021-11-26 02:25:48 +01:00
use std::ops::Deref;
2022-03-16 18:10:59 +01:00
use std::sync::Arc;
2022-03-16 18:10:59 +01:00
use rkyv::{AlignedVec, Archive, Archived, Deserialize, out_field, Serialize};
2022-03-13 20:11:37 +01:00
use serde::de::{Error, MapAccess, Unexpected};
2021-11-26 02:25:48 +01:00
use serde::Deserializer;
use serde::ser::SerializeMap;
2022-03-15 20:00:43 +01:00
2022-03-13 20:11:37 +01:00
use crate::MachineState;
use crate::resources::modules::fabaccess::OID_VALUE;
2021-11-26 02:25:48 +01:00
use crate::utils::oid::ObjectIdentifier;
2022-03-15 20:00:43 +01:00
pub mod value;
2021-11-26 21:01:43 +01:00
pub mod db;
2021-10-18 10:39:31 +02:00
#[derive(Archive, Serialize, Deserialize)]
2022-03-13 20:11:37 +01:00
#[derive(Clone, PartialEq, Eq)]
2021-10-18 11:27:42 +02:00
#[archive_attr(derive(Debug))]
pub struct State {
2022-03-13 20:11:37 +01:00
pub inner: MachineState,
}
2021-10-18 10:39:31 +02:00
impl fmt::Debug for State {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut sf = f.debug_struct("State");
2022-03-13 20:11:37 +01:00
//for Entry { oid, val } in self.inner.iter() {
let k: String = OID_VALUE.deref().into();
sf.field(k.as_ref(), &self.inner);
//}
sf.finish()
}
}
2022-03-13 20:11:37 +01:00
impl serde::Serialize for State {
2021-10-18 10:39:31 +02:00
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
let mut ser = serializer.serialize_map(Some(1))?;
2022-03-13 20:11:37 +01:00
ser.serialize_entry(OID_VALUE.deref(), &self.inner)?;
2021-10-18 10:39:31 +02:00
ser.end()
}
}
2022-03-13 20:11:37 +01:00
impl<'de> serde::Deserialize<'de> for State {
2021-10-18 10:39:31 +02:00
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
2022-03-13 20:11:37 +01:00
deserializer.deserialize_map(StateVisitor)
2021-10-18 10:39:31 +02:00
}
}
2022-03-13 20:11:37 +01:00
struct StateVisitor;
impl<'de> serde::de::Visitor<'de> for StateVisitor {
type Value = State;
2021-10-18 10:39:31 +02:00
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
2022-03-13 20:11:37 +01:00
write!(formatter, "a map from OIDs to value objects")
2021-10-18 10:39:31 +02:00
}
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error>
{
let oid: ObjectIdentifier = map.next_key()?
.ok_or(A::Error::missing_field("oid"))?;
2022-03-13 20:11:37 +01:00
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 })
2021-10-18 10:39:31 +02:00
}
}
2021-10-27 21:32:50 +02:00
#[cfg(test)]
pub mod tests {
use super::*;
2021-11-26 02:25:48 +01:00
use super::value::*;
2021-10-27 21:32:50 +02:00
pub(crate) fn gen_random() -> State {
let amt: u8 = rand::random::<u8>() % 20;
let mut sb = State::build();
for _ in 0..amt {
2021-11-26 02:25:48 +01:00
let oid = crate::utils::oid::tests::gen_random();
2021-10-27 21:32:50 +02:00
sb = match rand::random::<u32>()%12 {
0 => sb.add(oid, Box::new(rand::random::<bool>())),
1 => sb.add(oid, Box::new(rand::random::<u8>())),
2 => sb.add(oid, Box::new(rand::random::<u16>())),
3 => sb.add(oid, Box::new(rand::random::<u32>())),
4 => sb.add(oid, Box::new(rand::random::<u64>())),
5 => sb.add(oid, Box::new(rand::random::<u128>())),
6 => sb.add(oid, Box::new(rand::random::<i8>())),
7 => sb.add(oid, Box::new(rand::random::<i16>())),
8 => sb.add(oid, Box::new(rand::random::<i32>())),
9 => sb.add(oid, Box::new(rand::random::<i64>())),
10 => sb.add(oid, Box::new(rand::random::<i128>())),
11 => sb.add(oid, Box::new(rand::random::<Vec3u8>())),
_ => 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);
}
}