1

In the serde_json library, is it possible to parse json and map one property name to a different property name in the Rust struct?

For example, parse this json:

{
    "json_name": 3
}

into this struct:

StructName { struct_name: 3 }

Notice that "json_name" and "struct_name" are different.

Test
  • 962
  • 9
  • 26

1 Answers1

4

You can use a field attribute to tell serde that you want to use a name other than what you called the field in Rust. This tells serde that the json field data should be written to the struct's new_data field:

use serde::Deserialize;
use serde_json;

static JSON: &'static str = r#"{ "data": 4 }"#;

#[derive(Deserialize)]
struct Foo {
    data: u8,
}

#[derive(Deserialize)]
struct Bar {
    #[serde(rename = "data")]
    new_data: u8,
}

fn main() {
    let foo: Foo = serde_json::from_str(JSON).unwrap();
    let bar: Bar = serde_json::from_str(JSON).unwrap();

    assert_eq!(foo.data, bar.new_data);
}

Note: you'll need the derive crate feature for serde (serde = { version = "1.0", features = ["derive"] } in Cargo.toml), and make sure that the structs you're using with the JSON data have the appropriate derive macros.

Jeremy Meadows
  • 2,314
  • 1
  • 6
  • 22
  • 1
    I get `cannot find attribute serde in this scope serde is in scope, but it is a crate, not an attribute`. Do you need to compile this with some kind of compiler flag? – Test Jun 24 '22 at 21:31
  • 1
    @Test sorry, yes. I forgot that the playground has a bunch of features enabled for the crates it has built-in. you'll want `serde = { version = "1.0", features = ["derive"] }` in your `Cargo.toml` – Jeremy Meadows Jun 24 '22 at 21:52
  • 1
    oh wait, my macro error was about `#[derive(Deserialize)]`, not about `#[serde(...)]`. maybe you forgot `use serde` or something? – Jeremy Meadows Jun 24 '22 at 21:54