keyvalues-parser 0.2.3

A parser/renderer for vdf text
Documentation
use std::{borrow::Cow, collections::BTreeMap, fmt};

use crate::{Obj, Value};

use serde_core::{
    de::{MapAccess, Visitor},
    Deserialize, Deserializer,
};

fn value_string(s: impl ToString) -> Value<'static> {
    Value::Str(s.to_string().into())
}

struct ValueVisitor;

impl<'a> Visitor<'a> for ValueVisitor {
    type Value = Value<'a>;

    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("any valid VDF value")
    }

    fn visit_borrowed_str<E>(self, s: &'a str) -> Result<Self::Value, E> {
        Ok(Value::Str(Cow::Borrowed(s)))
    }

    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> {
        Ok(value_string(s))
    }

    fn visit_string<E>(self, s: String) -> Result<Self::Value, E> {
        Ok(Value::Str(Cow::Owned(s)))
    }

    fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
    where
        V: MapAccess<'a>,
    {
        let mut obj = BTreeMap::new();
        while let Some((key, value)) = visitor.next_entry()? {
            obj.insert(key, value);
        }
        Ok(Value::Obj(crate::Obj(obj)))
    }
}

impl<'de: 'a, 'a> Deserialize<'de> for Value<'a> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(ValueVisitor)
    }
}

struct ObjVisitor;

impl<'a> Visitor<'a> for ObjVisitor {
    type Value = Obj<'a>;

    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("an object")
    }

    fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
    where
        V: MapAccess<'a>,
    {
        let mut obj = BTreeMap::new();
        while let Some((key, value)) = visitor.next_entry()? {
            obj.insert(key, value);
        }
        Ok(Obj(obj))
    }
}

impl<'de: 'a, 'a> Deserialize<'de> for Obj<'a> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_map(ObjVisitor)
    }
}