Skip to content

Commit

Permalink
add serde support
Browse files Browse the repository at this point in the history
wip
  • Loading branch information
zkat committed Dec 9, 2024
1 parent cbadb35 commit 1587661
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ rust-version = "1.56.0"
edition = "2021"

[features]
default = ["span"]
default = ["span", "serde"]
span = []

[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"] }

Expand Down
235 changes: 235 additions & 0 deletions src/de.rs
Original file line number Diff line number Diff line change
@@ -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<Located<&'de str>, 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<T, KdlParseFailure>
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<T: std::fmt::Display>(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<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: de::MapAccess<'de>,
{
while let Some(key) = map.next_key()? {
match key {
"type" => {
let value = map.next_value::<String>()?;
println!("type: {}", value);
}
"value" => {
let value = map.next_value::<String>()?;
println!("value: {}", value);
}
_ => {
map.next_value::<serde::de::IgnoredAny>()?;
}
}
}

Ok(())
}
}

impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
type Error = DeError;

fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_map(visitor)
}

fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_unit_struct<V>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_newtype_struct<V>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_tuple_struct<V>(
self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_enum<V>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}

fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}
}
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,8 @@ mod node;
mod value;

mod v2_parser;

#[cfg(feature = "serde")]
pub mod de;
#[cfg(feature = "serde")]
pub mod se;
1 change: 1 addition & 0 deletions src/se.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit 1587661

Please sign in to comment.