Как десериализовать таблицу TOML, содержащую массив таблиц - PullRequest
0 голосов
/ 09 марта 2020

Возьмите следующие данные TOML:

[[items]]
foo = 10
bar = 100

[[items]]
foo = 12
bar = 144

И следующий код ржавчины:

use serde_derive::Deserialize;
use toml::from_str;
use toml::value::Table;

#[derive(Deserialize)]
struct Item {
    foo: String,
    bar: String
}

fn main() {
    let items_string: &str = "[[items]]\nfoo = 10\nbar = 100\n\n[[items]]\nfoo = 12\nbar = 144\n";
    let items_table: Table = from_str(items_string).unwrap();
    let items: Vec<Item> = items_table["items"].as_array().unwrap().to_vec();
    // Uncomment this line to print the table
    // println!("{:?}", items_table);
}

Как видите, программа не компилируется , возвращая эту ошибку:

ожидаемая структура Item, найдено enum toml::value::Value

Я понимаю его значение, но не знаю, как я мог решить эту проблему и добиться того, что я хотел сделать в первую очередь: преобразовать дочерний массив родительской таблицы в массив структур, а НЕ в массив таблиц.

1 Ответ

2 голосов
/ 09 марта 2020

Вы можете анализировать предопределенные типы TOML, такие как Table, но эти типы не знают о типах, кроме предопределенных. Эти типы чаще всего используются, когда фактический тип данных неизвестен или не важен.

В вашем случае это означает, что тип TOML Table не знает о вашем типе Item и не может быть выполнен знать об этом.

Однако вы можете легко разобрать другой тип:

use serde_derive::Deserialize;
use std::collections::HashMap;
use toml::from_str;

#[derive(Deserialize, Debug)]
struct Item {
    foo: u64,
    bar: u64,
}

fn main() {
    let items_string: &str = "[[items]]\nfoo = 10\nbar = 100\n\n[[items]]\nfoo = 12\nbar = 144\n";
    let items_table: HashMap<String, Vec<Item>> = from_str(items_string).unwrap();
    let items: &[Item] = &items_table["items"];

    println!("{:?}", items_table);
    println!("{:?}", items);
}

( Постоянная ссылка на игровую площадку )

...