#![allow(unused_variables)] use crate::schema; use microrm::prelude::*; use super::Config; struct ValueToStringSerializer {} impl<'l> serde::Serializer for &'l ValueToStringSerializer { type Ok = Option; type Error = ConfigError; type SerializeSeq = serde::ser::Impossible; type SerializeMap = serde::ser::Impossible; type SerializeTuple = serde::ser::Impossible; type SerializeStruct = serde::ser::Impossible; type SerializeTupleStruct = serde::ser::Impossible; type SerializeTupleVariant = serde::ser::Impossible; type SerializeStructVariant = serde::ser::Impossible; fn serialize_bool(self, v: bool) -> Result { unreachable!() } fn serialize_i8(self, v: i8) -> Result { self.serialize_i64(v as i64) } fn serialize_i16(self, v: i16) -> Result { self.serialize_i64(v as i64) } fn serialize_i32(self, v: i32) -> Result { self.serialize_i64(v as i64) } fn serialize_i64(self, v: i64) -> Result { Ok(Some(v.to_string())) } fn serialize_i128(self, v: i128) -> Result { unreachable!() } fn serialize_u8(self, v: u8) -> Result { self.serialize_u64(v as u64) } fn serialize_u16(self, v: u16) -> Result { self.serialize_u64(v as u64) } fn serialize_u32(self, v: u32) -> Result { self.serialize_u64(v as u64) } fn serialize_u64(self, v: u64) -> Result { Ok(Some(v.to_string())) } fn serialize_u128(self, v: u128) -> Result { unreachable!() } fn serialize_f32(self, v: f32) -> Result { unreachable!() } fn serialize_f64(self, v: f64) -> Result { unreachable!() } fn serialize_char(self, v: char) -> Result { unreachable!() } fn serialize_bytes(self, v: &[u8]) -> Result { unreachable!() } fn serialize_str(self, v: &str) -> Result { Ok(Some(v.into())) } fn serialize_none(self) -> Result { Ok(None) } fn serialize_some( self, value: &T, ) -> Result { value.serialize(self) } fn serialize_unit(self) -> Result { unreachable!() } fn serialize_seq(self, _len: Option) -> Result { unreachable!() } fn serialize_map(self, _len: Option) -> Result { unreachable!() } fn serialize_tuple(self, _len: usize) -> Result { unreachable!() } fn serialize_struct( self, _name: &'static str, _len: usize, ) -> Result { unreachable!() } fn serialize_unit_struct(self, name: &'static str) -> Result { unreachable!() } fn serialize_unit_variant( self, name: &'static str, variant_index: u32, variant: &'static str, ) -> Result { unreachable!() } fn serialize_tuple_struct( self, name: &'static str, len: usize, ) -> Result { unreachable!() } fn serialize_tuple_variant( self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result { todo!() } fn serialize_newtype_struct( self, name: &'static str, value: &T, ) -> Result { todo!() } fn serialize_struct_variant( self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result { todo!() } fn serialize_newtype_variant( self, name: &'static str, variant_index: u32, variant: &'static str, value: &T, ) -> Result { todo!() } } pub struct ConfigSerializer<'r, 's> { pub config: &'r Config, pub db: &'s schema::UIDCDatabase, pub prefix: String, } impl<'r, 's> ConfigSerializer<'r, 's> { fn update(&self, key: &str, value: String) { // TODO: delete old config value // self.db.persistent_config.delete(schema::PersistentConfig { key: key.into(), value }).expect("couldn't update config"); self.db .persistent_config .insert(schema::PersistentConfig { key: key.into(), value, }) .expect("couldn't update config"); } } impl<'r, 's> serde::ser::SerializeStruct for ConfigSerializer<'r, 's> { type Ok = (); type Error = ConfigError; fn serialize_field( &mut self, key: &'static str, value: &T, ) -> Result<(), Self::Error> { let key = format!("{}{}", self.prefix, key); let value = value.serialize(&ValueToStringSerializer {})?; if let Some(value) = value { log::trace!("saving config {} = {}", key, value); self.update(key.as_str(), value); } Ok(()) } fn end(self) -> Result { Ok(()) } } impl<'r, 's> serde::Serializer for &'r ConfigSerializer<'r, 's> { type Ok = (); type Error = ConfigError; type SerializeSeq = serde::ser::Impossible; type SerializeMap = serde::ser::Impossible; type SerializeTuple = serde::ser::Impossible; type SerializeStruct = ConfigSerializer<'r, 's>; type SerializeTupleStruct = serde::ser::Impossible; type SerializeTupleVariant = serde::ser::Impossible; type SerializeStructVariant = serde::ser::Impossible; fn serialize_bool(self, v: bool) -> Result { unreachable!() } fn serialize_i8(self, v: i8) -> Result { self.serialize_i64(v as i64) } fn serialize_i16(self, v: i16) -> Result { self.serialize_i64(v as i64) } fn serialize_i32(self, v: i32) -> Result { self.serialize_i64(v as i64) } fn serialize_i64(self, v: i64) -> Result { todo!() } fn serialize_i128(self, v: i128) -> Result { unreachable!() } fn serialize_u8(self, v: u8) -> Result { self.serialize_u64(v as u64) } fn serialize_u16(self, v: u16) -> Result { self.serialize_u64(v as u64) } fn serialize_u32(self, v: u32) -> Result { self.serialize_u64(v as u64) } fn serialize_u64(self, v: u64) -> Result { todo!() } fn serialize_u128(self, v: u128) -> Result { unreachable!() } fn serialize_f32(self, v: f32) -> Result { unreachable!() } fn serialize_f64(self, v: f64) -> Result { unreachable!() } fn serialize_char(self, v: char) -> Result { unreachable!() } fn serialize_bytes(self, v: &[u8]) -> Result { todo!() } fn serialize_str(self, v: &str) -> Result { todo!() } fn serialize_none(self) -> Result { Ok(()) } fn serialize_some( self, value: &T, ) -> Result { todo!() } fn serialize_unit(self) -> Result { unreachable!() } fn serialize_seq(self, len: Option) -> Result { todo!() } fn serialize_map(self, len: Option) -> Result { todo!() } fn serialize_tuple(self, len: usize) -> Result { todo!() } fn serialize_struct( self, name: &'static str, _len: usize, ) -> Result { log::trace!("name: {name}"); let new_prefix = // are we at the root? if name == "Config" { String::new() } else { format!("{}{}.", self.prefix, name) }; let subser = ConfigSerializer { config: self.config, db: self.db, prefix: new_prefix, }; Ok(subser) } fn serialize_unit_struct(self, name: &'static str) -> Result { todo!() } fn serialize_unit_variant( self, name: &'static str, variant_index: u32, variant: &'static str, ) -> Result { todo!() } fn serialize_tuple_struct( self, name: &'static str, len: usize, ) -> Result { todo!() } fn serialize_tuple_variant( self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result { todo!() } fn serialize_newtype_struct( self, name: &'static str, value: &T, ) -> Result { todo!() } fn serialize_struct_variant( self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result { todo!() } fn serialize_newtype_variant( self, name: &'static str, variant_index: u32, variant: &'static str, value: &T, ) -> Result { todo!() } } pub struct ConfigDeserializer<'de> { pub config_map: &'de std::collections::HashMap, pub prefix: String, } #[derive(Debug)] pub enum ConfigError { Missing(String), InvalidType(String), CustomError(String), } impl std::fmt::Display for ConfigError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Missing(what) => f.write_fmt(format_args!( "Missing required config entry: {}", what.as_str() )), Self::InvalidType(what) => f.write_fmt(format_args!( "Could not parse config entry '{}'", what.as_str() )), Self::CustomError(what) => { f.write_fmt(format_args!("Custom error '{}'", what.as_str())) } } } } impl std::error::Error for ConfigError {} impl serde::ser::Error for ConfigError { fn custom(msg: T) -> Self where T: std::fmt::Display, { Self::CustomError(msg.to_string()) } } impl serde::de::Error for ConfigError { fn custom(msg: T) -> Self where T: std::fmt::Display, { Self::CustomError(msg.to_string()) } fn invalid_type(_unexp: serde::de::Unexpected, _exp: &dyn serde::de::Expected) -> Self { Self::InvalidType("".into()) } fn missing_field(field: &'static str) -> Self { Self::Missing(field.into()) } } impl<'de> serde::Deserializer<'de> for &'de mut ConfigDeserializer<'de> { type Error = ConfigError; fn deserialize_any(self, _visitor: V) -> Result where V: serde::de::Visitor<'de>, { unreachable!("deserialize_any needs context") } fn deserialize_struct( self, _name: &'static str, _fields: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { self.deserialize_map(visitor) } fn deserialize_seq(self, _visitor: V) -> Result where V: serde::de::Visitor<'de>, { todo!("deserialize_seq") } fn deserialize_map(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let mut map_access = ConfigDeserializerIterator { it: self .config_map .iter() .filter(|e| { e.0.starts_with(&self.prefix) && !e.0[self.prefix.len()..].contains('.') }) .peekable(), }; visitor.visit_map(&mut map_access) } fn deserialize_enum( self, _name: &'static str, _variants: &'static [&'static str], _visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { todo!("deserialize_enum") } fn deserialize_tuple(self, _len: usize, _visitor: V) -> Result where V: serde::de::Visitor<'de>, { todo!("deserialize_tuple") } fn deserialize_tuple_struct( self, _name: &'static str, _len: usize, _visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { todo!("deserialize_tuple_struct") } serde::forward_to_deserialize_any!( i8 u8 i16 u16 i32 u32 i64 u64 i128 u128 str string bytes bool f32 f64 char byte_buf option unit unit_struct newtype_struct identifier ignored_any ); } struct AtomicForwarder<'de> { to_fwd: &'de str, } impl<'de> serde::Deserializer<'de> for AtomicForwarder<'de> { type Error = ConfigError; fn deserialize_any(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_unit() } fn deserialize_u64(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_u64( self.to_fwd .parse() .map_err(|_| ConfigError::InvalidType(String::new()))?, ) } fn deserialize_str(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_str(self.to_fwd) } fn deserialize_string(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_str(self.to_fwd) } fn deserialize_identifier(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_str(self.to_fwd) } serde::forward_to_deserialize_any!( i8 u8 i16 u16 i32 u32 i64 i128 u128 bytes bool f32 f64 char byte_buf unit unit_struct option newtype_struct ignored_any struct tuple tuple_struct seq map enum ); } struct ConfigDeserializerIterator<'de, I: Iterator> { it: std::iter::Peekable, } impl<'de, I: Iterator> serde::de::MapAccess<'de> for ConfigDeserializerIterator<'de, I> { type Error = ConfigError; fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> where K: serde::de::DeserializeSeed<'de>, { if let Some(e) = self.it.peek() { let de = AtomicForwarder { to_fwd: e.0.as_str(), }; Ok(seed.deserialize(de).ok()) } else { Ok(None) } } fn next_value_seed(&mut self, seed: V) -> Result where V: serde::de::DeserializeSeed<'de>, { let value = self.it.next().unwrap(); let de = AtomicForwarder { to_fwd: value.1.as_str(), }; seed.deserialize(de) .map_err(|e| ConfigError::InvalidType(e.to_string())) } }