Свой вид значения в JSON в Rust
Иногда стандартный вид поля в строке не подходит. Тогда для типа пишут блок выполнения трейта сборки вручную, а не полагаются только на пометку над структурой.
Метод сборки получает средство записи и возвращает исход. Внутри можно записать число, строку или другой простой вид, хотя в Rust тип обернут в свою оболочку.
Сделаем тип длины в метрах, который в строке становится числом:
use serde::Serialize;
use serde::ser::Serializer;
use serde_json;
struct Meter(i32);
impl Serialize for Meter {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_i32(self.0)
}
}
#[derive(Serialize)]
struct Room {
name: String,
width: Meter,
}
fn main() {
let room = Room {
name: String::from("hall"),
width: Meter(4),
};
match serde_json::to_string(&room) {
Ok(text) => println!("{}", text),
Err(_) => println!("error"),
}
}
Поле width записалось как число
4, хотя в Rust это отдельный
тип-обертка. Блок выполнения сам выбрал
запись целого через serialize_i32.
Тот же тип можно положить в вектор, если элементы тоже собираются через трейт:
use serde::Serialize;
use serde::ser::Serializer;
use serde_json;
struct Meter(i32);
impl Serialize for Meter {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_i32(self.0)
}
}
fn main() {
let list = vec![Meter(1), Meter(2)];
match serde_json::to_string(&list) {
Ok(text) => println!("{}", text),
Err(_) => println!("error"),
}
}
Дан тип:
struct Code(i32);
impl Serialize for Code {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_i32(self.0)
}
}
Соберите строку для значения Code
с числом 9 и выведите ее через
разбор исхода.
Дана структура:
struct Span {
len: Meter,
}
Используйте Meter из урока,
соберите строку для длины 10
и скажите, как выглядит ключ "len"
в объекте.
Скажите, какой трейт нужно выполнить вручную, чтобы свой тип записывался в строку не как объект с одним полем.