Serde обеспечивает serde_json::Value
( ссылка ).Это перечисление, которое содержит типы данных, такие как:
pub enum Value {
/// Represents a JSON null value.
Null,
/// Represents a JSON boolean.
Bool(bool),
/// Represents a JSON number, whether integer or floating point.
Number(Number),
/// Represents a JSON string.
String(String),
/// Represents a JSON array.
Array(Vec<Value>),
/// Represents a JSON object.
Object(Map<String, Value>),
}
Вы можете использовать serde_json::Value
в качестве типа значения для вашей HashMap.Просто можно получить данные из serde_json::Value
с помощью serde_json :: from_value или использовать сопоставление с образцом.В вашем случае я бы использовал сопоставление с образцом, потому что только Integer
типы будут преобразованы в String
, а остальные будут такими же.
Но вам нужно подумать о добавлении еще одного шага после десериализации.Как и
- Создание теневого поля для
custom
будет заполнено после десериализации. - Или создание новой структуры, содержащей
custom
как HashMap<String, String>
. - Добавить функцию для преобразования
HashMap<String, Value>
в HashMap<String, String>
,
Реализация этой черты может решить вашу проблему.
trait ToStringStringMap {
fn to_string_string_map(&self) -> HashMap<String, String>;
}
impl ToStringStringMap for HashMap<String, Value> {
fn to_string_string_map(&self) -> HashMap<String, String> {
self.iter()
.map(|(k, v)| {
let v = match v.clone() {
e @ Value::Number(_) | e @ Value::Bool(_) => e.to_string(),
Value::String(s) => s,
_ => {
println!(r#"Warning : Can not convert field : "{}'s value to String, It will be empty string."#, k);
"".to_string()
}
};
(k.clone(), v)
})
.collect()
}
}
Пример : Детская площадка
Примечание : Название черты выбрано неправильно, предложения приветствуются.