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

153 lines
4.5 KiB
Rust
Raw Normal View History

2022-03-16 18:10:59 +01:00
use std::fmt::{Debug, Display, Formatter};
2022-05-05 15:50:44 +02:00
use std::{fmt, hash::Hasher};
2022-04-26 23:21:43 +02:00
2021-11-26 02:25:48 +01:00
use std::ops::Deref;
2022-05-05 15:50:44 +02:00
use rkyv::{out_field, Archive, Deserialize, 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::ser::SerializeMap;
2022-05-05 15:50:44 +02:00
use serde::Deserializer;
2021-11-26 02:25:48 +01:00
2022-03-13 20:11:37 +01:00
use crate::resources::modules::fabaccess::OID_VALUE;
2022-05-05 15:50:44 +02:00
use crate::MachineState;
2021-11-26 02:25:48 +01:00
use crate::utils::oid::ObjectIdentifier;
2022-03-15 20:00:43 +01:00
2021-11-26 21:01:43 +01:00
pub mod db;
2022-05-05 15:50:44 +02:00
pub mod value;
2021-10-18 10:39:31 +02:00
2022-05-05 15:50:44 +02:00
#[derive(Archive, Serialize, Deserialize, 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-20 22:46:04 +01:00
impl fmt::Display for ArchivedState {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
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>
2022-05-05 15:50:44 +02:00
where
S: serde::Serializer,
2021-10-18 10:39:31 +02:00
{
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>
2022-05-05 15:50:44 +02:00
where
D: Deserializer<'de>,
2021-10-18 10:39:31 +02:00
{
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
}
2022-05-05 15:50:44 +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() {
2022-05-05 15:50:44 +02:00
return Err(A::Error::invalid_value(
Unexpected::Other("Unknown OID"),
&"OID of fabaccess state",
));
2022-03-13 20:11:37 +01:00
}
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 {
2021-11-26 02:25:48 +01:00
use super::value::*;
2022-05-05 15:50:44 +02:00
use super::*;
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();
2022-05-05 15:50:44 +02:00
sb = match rand::random::<u32>() % 12 {
2021-10-27 21:32:50 +02:00
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);
}
2022-05-05 15:50:44 +02:00
}