Метки полей JSON в Rust
По умолчанию ключ в строке совпадает с именем поля в Rust. Когда в файле или ответе сервера ключ написан иначе, над полем ставят атрибут с переименованием: внутри указывают, как ключ должен называться в объекте формата.
Запись пишут прямо над полем вместе с пометкой, которая подключает трейты сборки и разбора. Имя в Rust остается удобным для кода, а наружу уходит другое имя ключа.
Из корня проекта добавим крейт с пометками и крейт для работы со строкой формата:
cargo add serde --features derive
cargo add serde_json
Команды допишут зависимости в описание
пакета. Дальше правим src/main.rs.
Объявим пользователя с переименованным полем имени и соберем строку:
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct User {
#[serde(rename = "user_name")]
name: String,
age: i32,
}
fn main() {
let user = User {
name: String::from("ann"),
age: 20,
};
match serde_json::to_string(&user) {
Ok(text) => println!("{}", text),
Err(_) => println!("error"),
}
}
На экране объект с ключом "user_name",
а не "name". Атрибут
#[serde(rename = "user_name")]
меняет только внешнее имя, поле в коде
по-прежнему name.
Разберем ту же строку обратно, если ключи совпали с метками:
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct User {
#[serde(rename = "user_name")]
name: String,
age: i32,
}
fn main() {
let text = r#"{"user_name":"ann","age":20}"#;
match serde_json::from_str::<User>(text) {
Ok(user) => println!("{} {}", user.name, user.age),
Err(_) => println!("error"),
}
}
Дана структура:
struct Point {
x: i32,
y: i32,
}
Подключите трейты сборки и разбора,
задайте ключи "pos_x" и "pos_y",
соберите точку с координатами 1
и 2 и выведите строку.
Дана структура:
struct Tag {
label: String,
}
Переименуйте поле в ключ "tag_label",
разберите строку {"tag_label":"go"}
и выведите подпись.
Скажите, где в коде задают имя ключа, отличное от имени поля, и меняется ли имя поля в Rust после такой записи.