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};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ReferenceKind {
Object,
Value,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Reference {
kind: ReferenceKind,
number: u64,
}
impl Reference {
pub const fn new(kind: ReferenceKind, number: u64) -> Reference {
Reference { kind, number }
}
pub const fn kind(self) -> ReferenceKind {
self.kind
}
pub const fn number(self) -> u64 {
self.number
}
}
impl Extension for Reference {
fn name(&self) -> &str {
"php reference"
}
fn fallback(&self) -> Atom<'_> {
Atom::U64(self.number)
}
}
impl Serialize for Reference {
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 Reference {
fn deserialize_atom(slot: &mut Slot<Self>, atom: Atom, state: &mut State) -> Result<(), Error> {
match atom {
Atom::Ext(ref ext) => match ext.downcast_ref::<Reference>() {
Some(&value) => {
slot.set(value);
Ok(())
}
None => default_atom(slot, atom, state),
},
other => default_atom(slot, other, state),
}
}
fn expecting() -> Cow<'static, str> {
Cow::Borrowed("php reference")
}
}