Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to leave all strings escaped? #787

Open
rw opened this issue Jul 22, 2021 · 1 comment
Open

Is it possible to leave all strings escaped? #787

rw opened this issue Jul 22, 2021 · 1 comment
Labels

Comments

@rw
Copy link

rw commented Jul 22, 2021

Is it possible to leave all strings escaped? For example, in a Visitor, I would like the following JSON to invoke the following Visitor calls:

{"abc\"def": "012\"345"}
// visit map elements:
visit_borrowed_str // for a &'de str "abc\"def"
visit_borrowed_str // for a &'de str "012\"345"

instead of these visitor calls:

// visit map elements:
visit_string // for a Cow<'de, str>::Owned(r#"abc"def"#)
visit_string // for a Cow<'de, str>::Owned(r#"012"345"#)

Thanks!

@dtolnay
Copy link
Member

dtolnay commented Jan 23, 2022

Yes you could wrap the JSON deserializer so that it does not do any unescaping. Something like:

// [dependencies]
// serde = "1.0"
// serde_json = { version = "1.0.78", features = ["raw_value"] }

use serde::de::value::BorrowedStrDeserializer;
use serde::de::{Deserialize, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor};
use serde_json::value::RawValue;
use std::collections::HashMap;
use std::fmt;

fn main() {
    let j = r#" {"abc\"def": "012\"345"} "#;
    let mut de = serde_json::Deserializer::from_str(j);
    let map = HashMap::<&str, &str>::deserialize(NoUnescape(&mut de)).unwrap();
    for (k, v) in map {
        println!("{} = {}", k, v);
    }
}

struct NoUnescape<D>(D);

impl<'de, D> Visitor<'de> for NoUnescape<D>
where
    D: Visitor<'de>,
{
    type Value = D::Value;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.expecting(formatter)
    }

    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
    where
        A: MapAccess<'de>,
    {
        self.0.visit_map(NoUnescape(map))
    }

    fn visit_seq<A>(self, map: A) -> Result<Self::Value, A::Error>
    where
        A: SeqAccess<'de>,
    {
        self.0.visit_seq(NoUnescape(map))
    }
}

impl<'de, D> MapAccess<'de> for NoUnescape<D>
where
    D: MapAccess<'de>,
{
    type Error = D::Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
    where
        K: DeserializeSeed<'de>,
    {
        let json = match self.0.next_key::<&RawValue>()? {
            None => return Ok(None),
            Some(raw_value) => raw_value.get(),
        };
        let string = &json[1..json.len() - 1];
        let key = seed.deserialize(BorrowedStrDeserializer::new(string))?;
        Ok(Some(key))
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
    where
        V: DeserializeSeed<'de>,
    {
        let json = self.0.next_value::<&RawValue>()?.get();
        if json.starts_with('"') {
            let string = &json[1..json.len() - 1];
            seed.deserialize(BorrowedStrDeserializer::new(string))
        } else {
            let mut de = serde_json::Deserializer::from_str(json);
            seed.deserialize(NoUnescape(&mut de))
                .map_err(serde::de::Error::custom)
        }
    }
}

impl<'de, D> SeqAccess<'de> for NoUnescape<D>
where
    D: SeqAccess<'de>,
{
    type Error = D::Error;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
    where
        T: DeserializeSeed<'de>,
    {
        let json = match self.0.next_element::<&RawValue>()? {
            None => return Ok(None),
            Some(raw_value) => raw_value.get(),
        };
        if json.starts_with('"') {
            let string = &json[1..json.len() - 1];
            seed.deserialize(BorrowedStrDeserializer::new(string))
                .map(Some)
        } else {
            let mut de = serde_json::Deserializer::from_str(json);
            seed.deserialize(NoUnescape(&mut de))
                .map(Some)
                .map_err(serde::de::Error::custom)
        }
    }
}

impl<'de, D> Deserializer<'de> for NoUnescape<D>
where
    D: Deserializer<'de>,
{
    type Error = D::Error;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    fn deserialize_struct<V>(
        self,
        _name: &'static str,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

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

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants