From a85107d39aa1d0d09dd0d4a3633518c9c7fcbd9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Tue, 8 Oct 2024 22:44:00 -0700 Subject: [PATCH] add serde support wip --- Cargo.toml | 3 +- src/de.rs | 235 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 5 ++ src/se.rs | 1 + 4 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 src/de.rs create mode 100644 src/se.rs diff --git a/Cargo.toml b/Cargo.toml index e317dd4..66a4812 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.70.0" edition = "2021" [features] -default = ["span"] +default = ["span", "serde"] span = [] v1-fallback = ["v1"] v1 = ["kdlv1"] @@ -20,6 +20,7 @@ v1 = ["kdlv1"] [dependencies] miette = "7.2.0" num = "0.4.2" +serde = { version = "1.0.210", optional = true } thiserror = "1.0.40" winnow = { version = "0.6.20", features = ["alloc", "unstable-recover"] } kdlv1 = { package = "kdl", version = "4.7.0", optional = true } diff --git a/src/de.rs b/src/de.rs new file mode 100644 index 0000000..a1a1d06 --- /dev/null +++ b/src/de.rs @@ -0,0 +1,235 @@ +use serde::{de, Deserialize}; +use thiserror::Error; +use winnow::{stream::Recoverable, Located}; + +use crate::{v2_parser::KdlParseError, KdlParseFailure}; + +/// serde deserializer for KDL documents +#[derive(Debug)] +pub struct Deserializer<'de> { + input: Recoverable, KdlParseError>, +} + +impl<'de> Deserializer<'de> { + /// Create a new deserializer from a string + pub fn from_str(input: &'de str) -> Self { + Self { + input: Recoverable::new(Located::new(input)), + } + } +} + +/// Deserialize a type from a KDL string +pub fn from_str<'a, T>(input: &'a str) -> Result +where + T: Deserialize<'a>, +{ +} + +#[derive(Debug, Error)] +struct DeError(String); + +impl std::fmt::Display for DeError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl de::Error for DeError { + fn custom(msg: T) -> Self { + DeError(msg.to_string()) + } +} + +struct KdlVisitor; + +impl<'de> de::Visitor<'de> for KdlVisitor { + type Value = (); + + fn expecting<'a>(&self, formatter: &mut std::fmt::Formatter<'a>) -> std::fmt::Result { + write!(formatter, "a KDL value") + } + + fn visit_map(self, mut map: A) -> Result + where + A: de::MapAccess<'de>, + { + while let Some(key) = map.next_key()? { + match key { + "type" => { + let value = map.next_value::()?; + println!("type: {}", value); + } + "value" => { + let value = map.next_value::()?; + println!("value: {}", value); + } + _ => { + map.next_value::()?; + } + } + } + + Ok(()) + } +} + +impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { + type Error = DeError; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_map(visitor) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_unit_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_tuple_struct( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + todo!() + } +} diff --git a/src/lib.rs b/src/lib.rs index e3eff78..000418c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -208,3 +208,8 @@ mod node; mod value; mod v2_parser; + +#[cfg(feature = "serde")] +pub mod de; +#[cfg(feature = "serde")] +pub mod se; diff --git a/src/se.rs b/src/se.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/se.rs @@ -0,0 +1 @@ +