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
Labels
Comments
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
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:
instead of these visitor calls:
Thanks!
The text was updated successfully, but these errors were encountered: