Как десериализовать JSON, где типы значений указаны в другом поле?
Я не уверен, как я должен пытаться десериализовать некоторый JSON, который выглядит следующим образом:
{
"columns": [
{
"name": "stringColumn",
"type": "string"
},
{
"name": "DateColumn",
"type": "date"
},
{
"name": "NumberColumn",
"type": "number"
}
],
"data": [
[
"This is a string",
1548091093000,
123
]
]
}
columns
вектор описывает типы и количество записей внутри элемента data
вектор. Пример выше может быть преобразован в CSV как таковой (игнорируя типы):
stringColumn,DateColumn,NumberColumn
"This is a string",1548091093000,123
Некоторые дополнительные проблемы:
-
number
может быть целым числом или числом с плавающей запятой. Должен ли я представлять это как перечисление? - Большое количество
1548091093000
количество миллисекунд с начала UNIX (эквивалентноMonday, January 21, 2019 5:18:13 PM
). Поскольку у меня есть даты (используя эпоху) и числа, я не могу их легко отличить, не имея доступа к описанию "заголовка"... - Я использую
restson
вызвать API REST, который возвращает JSON выше. Рестсон позвонитserde_json::from_str()
с окончательным типом. Это означает, что этот тип должен реализовыватьDeserialize
,
Как я могу десериализовать это?
1 ответ
Ваши данные полностью, безнадежно динамичны, что означает, что вы не можете использовать какие-либо хорошие инструменты, такие как получение Deserialize
,
Вам нужно будет использовать serde_json::Value
перечисление всех возможных типов JSON для данных. Вы можете получить структуру для фиксированной структуры:
use serde_derive; // 1.0.84
use serde_json::{self, Value}; // 1.0.34
static INPUT: &str = r#"
{
"columns": [
{
"name": "stringColumn",
"type": "string"
},
{
"name": "DateColumn",
"type": "date"
},
{
"name": "NumberColumn",
"type": "number"
}
],
"data": [
[
"This is a string",
1548091093000,
123
]
]
}
"#;
#[derive(Debug, serde_derive::Deserialize)]
struct Thing {
columns: Vec<Column>,
data: Vec<Vec<Value>>,
}
#[derive(Debug, serde_derive::Deserialize)]
struct Column {
name: String,
r#type: String,
}
fn main() {
let data = serde_json::from_str::<Thing>(INPUT);
println!("{:#?}", data)
}
Число может быть целым или с плавающей точкой
Это уже обработано serde_json::Number
Смотрите также: