Question from IRC:
\
serde_json doesn't seem to be able to deserialize valid json with backslashes
\{"sms":"{\"Source\":4477665544,\"Destination\":1231231,\"Content\":\"Hello from SMPPSim\"}","uuid":"69e123f4-4ced-4f8f-9853-df20ebc3937b"}
\is no go
\i'm guessing you mean the inner json there
\?
\yep
\let me show you my code
\yeah, you'd have to unescape it first
\https://play.rust-lang.org/?gist=3fb18ca55def35c626508445c49606dc&version=stable
\How do I unescape it without touching the backslashes that might be inside the field's value?
\i don't know to be honest
\i've never seen JSON embedded inside of a string in JSON
\Go seems to handle such deserialization just fine
\gitstash: you'd probably want to first deserialize to a `struct Foo { sms: String }` and then reparse the sms field
\nested json seems pretty weird
\sfackler: That's messy
\gitstash: so is stringifying json and sticking it in json :P
\ill do as you say then
\thank you
@gitstash @steveklabnik @sfackler
\
Go seems to handle such deserialization just fine
I was not able to reproduce this.
package main
import (
"fmt"
"encoding/json"
)
type Message struct {
SMS SMS
UUID string
}
type SMS struct {
Source uint64
Destination uint64
Content string
}
func main() {
msg := `{
"sms":"{\"Source\":4477665544,\"Destination\":1231231,\"Content\":\"Hello from SMPPSim\"}",
"uuid":"69e123f4-4ced-4f8f-9853-df20ebc3937b"
}`
var de Message
err := json.Unmarshal([]byte(msg), &de)
if err != nil {
fmt.Println(err)
}
}
json: cannot unmarshal string into Go struct field Message.SMS of type main.SMS
In any case, here it is in Rust (with both serialize and deserialize).
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Message {
#[serde(with = "json_string")]
sms: Sms,
uuid: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
struct Sms {
source: u64,
destination: u64,
content: String,
}
mod json_string {
use serde_json;
use serde::ser::{self, Serialize, Serializer};
use serde::de::{self, Deserialize, DeserializeOwned, Deserializer};
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where T: Serialize,
S: Serializer
{
let j = serde_json::to_string(value).map_err(ser::Error::custom)?;
j.serialize(serializer)
}
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where T: DeserializeOwned,
D: Deserializer<'de>
{
let j = String::deserialize(deserializer)?;
serde_json::from_str(&j).map_err(de::Error::custom)
}
}
fn main() {
let msg = r#"
{
"sms":"{\"Source\":4477665544,\"Destination\":1231231,\"Content\":\"Hello from SMPPSim\"}",
"uuid":"69e123f4-4ced-4f8f-9853-df20ebc3937b"
}"#;
let de = serde_json::from_str::<Message>(msg).unwrap();
println!("{:#?}", de);
let ser = serde_json::to_string_pretty(&de).unwrap();
println!("{}", ser);
}
A candidate for attribute or a public module in serde_json
so we can write #[serde(with = "serde_json::nested")]
?
I added it to the list in #553.
Most helpful comment
In any case, here it is in Rust (with both serialize and deserialize).