use alloc::borrow::Cow;
use deser_core::State;
use deser_core::de::{Deserialize, Slot, default_atom};
use deser_core::ext::{ExtValue, Extension};
use deser_core::ser::{Emit, Serialize};
use deser_core::{Atom, Error, ErrorKind};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Simple(u8);
impl Simple {
pub fn new(value: u8) -> Option<Simple> {
if (24..32).contains(&value) {
None
} else {
Some(Simple(value))
}
}
pub fn value(self) -> u8 {
self.0
}
}
impl Extension for Simple {
fn name(&self) -> &str {
"simple value"
}
fn fallback(&self) -> Atom<'_> {
Atom::U64(u64::from(self.0))
}
}
impl Serialize for Simple {
fn serialize<'a>(value: &'a Self, _state: &mut State) -> Result<Emit<'a>, Error> {
Ok(Emit::Atom(Atom::Ext(ExtValue::borrowed(value))))
}
}
impl<'de> Deserialize<'de> for Simple {
fn deserialize_atom(slot: &mut Slot<Self>, atom: Atom, state: &mut State) -> Result<(), Error> {
let simple = match atom {
Atom::Ext(ref ext) if ext.is::<Simple>() => *ext.downcast_ref::<Simple>().unwrap(),
Atom::Bool(false) => Simple(20),
Atom::Bool(true) => Simple(21),
Atom::Null => Simple(22),
Atom::U64(value) => match u8::try_from(value).ok().and_then(Simple::new) {
Some(simple) => simple,
None => {
return Err(Error::new(
ErrorKind::OutOfRange,
"value out of range for simple value",
));
}
},
other => return default_atom(slot, other, state),
};
slot.set(simple);
Ok(())
}
fn expecting() -> Cow<'static, str> {
Cow::Borrowed("simple")
}
}