use crate::hydrus_serializable::wrapper::HydrusSerWrapper; use crate::FromJson; use serde::de::{DeserializeOwned, Error, Visitor}; use serde::{Deserialize, Deserializer}; use serde_json::Value; use std::fmt::Formatter; use std::marker::PhantomData; pub mod content_update; pub mod definitions_update; pub mod dictionary; pub mod metadata; pub mod tag_filter; pub mod wrapper; pub trait HydrusSerializable: DeserializeOwned { fn type_id() -> u64; } impl FromJson for T where T: HydrusSerializable, { fn from_json(value: Value) -> crate::Result where Self: Sized, { let wrapper = serde_json::from_value::>(value)?; Ok(wrapper.inner) } } pub trait ConstNumberTrait { fn value() -> u64; } impl ConstNumberTrait for T where T: HydrusSerializable, { fn value() -> u64 { T::type_id() } } #[derive(Clone, Debug)] pub struct SerializableId(u64, PhantomData); impl<'de, T: ConstNumberTrait> Deserialize<'de> for SerializableId { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_u64(SerIdVisitor(PhantomData)) } } struct SerIdVisitor(PhantomData); impl<'de, T: ConstNumberTrait> Visitor<'de> for SerIdVisitor { type Value = SerializableId; fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { write!(formatter, "an unsigned integer equal to {}", T::value()) } fn visit_u8(self, v: u8) -> Result where E: Error, { self.visit_u64(v as u64) } fn visit_u16(self, v: u16) -> Result where E: Error, { self.visit_u64(v as u64) } fn visit_u32(self, v: u32) -> Result where E: Error, { self.visit_u64(v as u64) } fn visit_u64(self, v: u64) -> Result where E: Error, { let expected_value = T::value(); if v != expected_value { Err(E::custom(format!("value not equal to {}", expected_value))) } else { Ok(SerializableId(expected_value, PhantomData)) } } }