1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
use serde::{ self, de::{Deserializer, MapAccess, Visitor}, Deserialize, }; use std::{fmt, marker::PhantomData}; pub trait FromKeyValue { type Key; type Value; fn from_key_value(key: Self::Key, value: Self::Value) -> Self; } pub struct KeyValueVecMap<T: FromKeyValue>(pub Vec<T>); impl<T: FromKeyValue> Into<Vec<T>> for KeyValueVecMap<T> { fn into(self) -> Vec<T> { self.0 } } struct KeyValueVecMapVisitor<T: FromKeyValue> { marker: PhantomData<fn() -> KeyValueVecMap<T>>, } impl<T: FromKeyValue> KeyValueVecMapVisitor<T> { fn new() -> Self { Self { marker: PhantomData, } } } impl<'de, T: FromKeyValue, K, V> Visitor<'de> for KeyValueVecMapVisitor<T> where T: FromKeyValue<Key = K, Value = V>, K: Deserialize<'de>, V: Deserialize<'de>, { type Value = KeyValueVecMap<T>; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("key value map") } fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error> where M: MapAccess<'de>, { let mut vec = Vec::with_capacity(access.size_hint().unwrap_or(0)); while let Some((key, value)) = access.next_entry()? { vec.push(T::from_key_value(key, value)); } Ok(KeyValueVecMap(vec)) } } impl<'de, T, K, V> Deserialize<'de> for KeyValueVecMap<T> where T: FromKeyValue<Key = K, Value = V>, K: Deserialize<'de>, V: Deserialize<'de>, { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { deserializer.deserialize_map(KeyValueVecMapVisitor::new()) } } #[test] fn test_deserialize() { let json = r#" { "temperature": 40, "pressure": 123 } "#; #[derive(Debug, Eq, PartialEq)] struct SingleMeasurement { name: String, value: u32, } impl FromKeyValue for SingleMeasurement { type Key = String; type Value = u32; fn from_key_value(key: Self::Key, value: Self::Value) -> Self { Self { name: key, value } } } let values: Vec<SingleMeasurement> = serde_json::from_str::<KeyValueVecMap<SingleMeasurement>>(json) .unwrap() .into(); assert_eq!( values, vec![ SingleMeasurement { name: "temperature".into(), value: 40 }, SingleMeasurement { name: "pressure".into(), value: 123 }, ] ); }