How to decode JSON object with Rust keyword attribute name?
Asked Answered
B

2

18

I was wondering if it is possible to decode a JSON object in Rust that has an attribute name which is also a Rust keyword. I am working with the rustc-serialize crate and my struct definition looks like this:

#[derive(RustcDecodable)]
struct MyObj {
  type: String
}

The compiler throws an error because type is a keyword:

error: expected identifier, found keyword `type`
src/mysrc.rs:23     type: String,
                           ^~~~
Bergeman answered 17/3, 2015 at 17:18 Comment(3)
Is it safe to assume that the original data can't be changed to avoid the conflict?Greggs
yes, it would be best if i didn't have to change the source data. I guess maybe creating a new struct field with a different name and writing a custom impl Decodable is the only way?Bergeman
I can see either manually implementing it or using Json::from_str and then poking into its result value.Greggs
E
27

You can use the serde crate. It supports renaming of fields since February 2015

Your example could then look like this:

#[derive(Deserialize)]
struct MyObj {
    #[serde(rename = "type")] 
    type_name: String
}
Epizoic answered 18/3, 2015 at 9:28 Comment(2)
Seems like exactly what i was looking for. It says it does some lookahead, do you know if it is possible to parse an attribute that could be one of a few different types? so a field called msg could be either a JSON string or an array.Bergeman
That is one of the main reasons serde was invented, because the old deserializer couldn't read an enum without having read a tag beforehand.Epizoic
P
1

This can be done without serde's field renaming by using raw identifiers. By adding r# in front of an identifier, a keyword name can be used.

Using rustc-serialize

#[derive(RustcDecodable)]
struct MyObj {
    r#type: String
}

Using serde

use serde::Deserialize;

#[derive(Deserialize)]
struct MyObj {
    r#type: String
}

Note that rustc-serialize is deprecated in favor of serde.

Pears answered 29/10, 2022 at 16:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.