These are chat archives for rust-lang/rust

5th
May 2017
Aliaksandr Rahalevich
@saks
May 05 2017 17:46
hey guys! I'm trying to parse json with another json nested as a string, but serde complains that I should be using String instead of &str (expected a borrowed string). Would be nice if someone can look at it here (http://play.integer32.com/?gist=9087bd27716632977997080614c43b08&version=undefined). Thanks.
Denis Lisov
@tanriol
May 05 2017 18:20
@saks The problem seems to be that you're trying to deserialize "zero-copy", borrowing the string inside your structure from the JSON string, but it's only there in escaped form, while you'd need it unescaped :-(
I'm afraid you need to use a String instead of &str in this case.
David Harvey-Macaulay
@alteous
May 05 2017 18:26
@tanriol This is plausible but I'm not so sure. Check out the output of this:
#[derive(Debug, Serialize)]
struct Item {
    a: String,
}

fn main() {
    let json = json!({
        "a": "\"123\"",
    });
    let json_string = serde_json::to_string(&json).unwrap();
    for c in json_string.chars() {
        print!("{}", c);
    }
    println!("{}", "");
    let item: Item = serde_json::from_str(&json_string).unwrap();
    println!("{:?}", item);
}
{"a":"\"123\""}
Item { a: "\"123\"" }
Edit: Added Item
Aliaksandr Rahalevich
@saks
May 05 2017 18:28
Thanks. I see. I know it works with String, but the point was to save some memory for weak device.
David Harvey-Macaulay
@alteous
May 05 2017 18:28
I can't see why the string "123" can't be borrowed.
Serhii Plyhun
@snuk182
May 05 2017 18:32
as far as I understand, that's because the code for parsing escaped chars comes here https://github.com/serde-rs/json/blob/master/src/read.rs#L567
David Harvey-Macaulay
@alteous
May 05 2017 18:34
I'm having trouble updating some code to serde 1.0. Is there any way of fixing this error? https://play.integer32.com/?gist=602232822b7db19ea797e2b3f297ade6&version=undefined
Denis Lisov
@tanriol
May 05 2017 18:34
@alteous There's no string "123" in the JSON text, only \"123\"
David Harvey-Macaulay
@alteous
May 05 2017 18:38
@tanriol This is confusing, excuse me.
My point was that if you change Item to the following serde complains:
#[derive(Debug, Serialize)]
struct Item {
    a: &'a str,
}
Denis Lisov
@tanriol
May 05 2017 18:41
@saks Try using a Cow<'a, str> instead of a &'a str. It does deserialize in both cases and, IIUC, does not allocate a new string unless really needed.
Aliaksandr Rahalevich
@saks
May 05 2017 18:42
@tanriol good catch! I'll try it out, thanks!
Denis Lisov
@tanriol
May 05 2017 18:44
@alteous Your a field contains a string with embedded quotes. You cannot borrow it from the JSON string because there's an extra backslash in the middle.
David Harvey-Macaulay
@alteous
May 05 2017 18:44
Ah, @tanriol you are right, forgive me. The allocation is necessary because the deserialized version of"\"foo\"" would be the str "foo", but the embedded quotes mean you can't avoid the backslash in the slice.
Serhii Plyhun
@snuk182
May 05 2017 18:57

You cannot borrow it from the JSON string because there's an extra backslash in the middle

Doesn't it look like a bug then?

Aliaksandr Rahalevich
@saks
May 05 2017 18:57
yeah... the same question
David Harvey-Macaulay
@alteous
May 05 2017 18:58
Not really because \" is defined to be a literal " in JSON.
Deserializing a JSON string "\"123\"" into "123\" would be a bug, because the string should really be "123".
Aliaksandr Rahalevich
@saks
May 05 2017 19:00
@alteous but it's really strange when parser behaves differently with two strings, both valid strings.
Serhii Plyhun
@snuk182
May 05 2017 19:00
Yeah but it is still escaped and caught between the non-escaped "'s, e.g. a string value, just the string with "s
mb that was done as a safeguard for the automatic type definition during the parse
Denis Lisov
@tanriol
May 05 2017 19:02
@saks Would you prefer it to just not compile with &'a str in your struct?
David Harvey-Macaulay
@alteous
May 05 2017 19:03
"\"123\"" is a valid JSON string, but it means "123". serde can't borrow the slice "123" because it contains the \, so it must make an allocation to remove the escape(s).
Aliaksandr Rahalevich
@saks
May 05 2017 19:04
@alteous I see now... Thanks for explanation
Serhii Plyhun
@snuk182
May 05 2017 19:05
aaah
thanks @alteous !
David Harvey-Macaulay
@alteous
May 05 2017 19:06
No problem. :) It's a bit confusing - especially when rustc prints this in the terminal:
"{\"a\":\"\\\"123\\\"\"}"
Aliaksandr Rahalevich
@saks
May 05 2017 19:08
@tanriol I'll try to use Cow<'a, str>