Один из способов решить эту проблему - сериализовать данные JSON с помощью serde_json
, а затем использовать временную карту для выбора этих значений. Я пропустил много проверок ошибок, но вот схема:
use serde_json::{Result, Value};
use std::collections::HashMap;
#[derive(Debug)]
struct Data {
some_other_field: String,
options: Vec<String>,
}
fn text_to_data(text: &str) -> Result<Data> {
let prefix: &'static str = "option";
// Deserialize JSON
let value: Value = serde_json::from_str(text)?;
let value_map = value.as_object().unwrap();
// Filter keys for "option*", cut prefix, convert to integer and store it in a map
let options_map: HashMap<usize, &str> = value_map.iter()
.filter(|it| it.0.starts_with(prefix))
.map(|it| (it.0[prefix.len()..].parse::<usize>().unwrap(), it.1.as_str().unwrap()))
.collect();
// Get the maximum of options
let options_count = options_map.iter().map(|it| it.0).max().unwrap();
// Collect values to a vector or use empty string as default
let options: Vec<String> = (0..=*options_count)
.map(|it| options_map.get(&it).unwrap_or(&"").to_string()).collect();
// Also access other fields in JSON
let some_other_field =
value.get("some_other_field").unwrap().as_str().unwrap().to_string();
Ok(Data { some_other_field, options })
}
fn main() {
let data = r#"
{
"some_other_field": "value",
"option1": "value1",
"option2": "value2",
"option10": "value10"
}"#;
let x = text_to_data(data);
println!("{:?}", x);
}
Вывод:
Ok(Data { some_other_field: "value", options: ["", "value1", "value2", "", "", "", "", "", "", "", "value10"] })