1use alloc::borrow::Cow;
2
3use deser_core::State;
4use deser_core::de::{Deserialize, Slot, default_atom};
5use deser_core::ext::{ExtValue, Extension};
6use deser_core::ser::{Emit, Serialize};
7use deser_core::{Atom, Error, ErrorKind};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
25pub struct Simple(u8);
26
27impl Simple {
28 pub fn new(value: u8) -> Option<Simple> {
33 if (24..32).contains(&value) {
34 None
35 } else {
36 Some(Simple(value))
37 }
38 }
39
40 pub fn value(self) -> u8 {
42 self.0
43 }
44}
45
46impl Extension for Simple {
47 fn name(&self) -> &str {
48 "simple value"
49 }
50
51 fn fallback(&self) -> Atom<'_> {
52 Atom::U64(u64::from(self.0))
53 }
54}
55
56impl Serialize for Simple {
57 fn serialize<'a>(value: &'a Self, _state: &mut State) -> Result<Emit<'a>, Error> {
58 Ok(Emit::Atom(Atom::Ext(ExtValue::borrowed(value))))
59 }
60}
61
62impl<'de> Deserialize<'de> for Simple {
63 fn deserialize_atom(slot: &mut Slot<Self>, atom: Atom, state: &mut State) -> Result<(), Error> {
64 let simple = match atom {
65 Atom::Ext(ref ext) if ext.is::<Simple>() => *ext.downcast_ref::<Simple>().unwrap(),
66 Atom::Bool(false) => Simple(20),
67 Atom::Bool(true) => Simple(21),
68 Atom::Null => Simple(22),
69 Atom::U64(value) => match u8::try_from(value).ok().and_then(Simple::new) {
70 Some(simple) => simple,
71 None => {
72 return Err(Error::new(
73 ErrorKind::OutOfRange,
74 "value out of range for simple value",
75 ));
76 }
77 },
78 other => return default_atom(slot, other, state),
79 };
80 slot.set(simple);
81 Ok(())
82 }
83
84 fn expecting() -> Cow<'static, str> {
85 Cow::Borrowed("simple")
86 }
87}