a small relational database with user-editable schema for manual data entry
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
yopa/yopa/src/serde_map_as_list.rs

54 lines
1.4 KiB

//! Serialize a HashMap of ID-keyed structs that also contain the ID inside
//! to a plain list, and also back when deserializing.
use std::collections::HashMap;
use crate::ID;
use serde::{Serialize, Deserializer, Deserialize, de};
use serde::ser::SerializeSeq;
use serde::de::{Visitor, SeqAccess, Unexpected};
use std::fmt;
use crate::id::HaveId;
use std::marker::PhantomData;
pub fn serialize<S, X>(x: &HashMap<ID, X>, s: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
X: Serialize + HaveId
{
let mut seq = s.serialize_seq(Some(x.len()))?;
for p in x.values() {
seq.serialize_element(p)?;
}
seq.end()
}
pub fn deserialize<'de, D, X>(deserializer: D) -> Result<HashMap<ID, X>, D::Error>
where
D: Deserializer<'de>,
X: Deserialize<'de> + HaveId
{
deserializer.deserialize_seq(SeqToMap(Default::default()))
}
pub struct SeqToMap<X>(PhantomData<X>);
impl<'de, X : Deserialize<'de> + HaveId> Visitor<'de> for SeqToMap<X> {
type Value = HashMap<ID, X>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("sequence of items with id")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut map = HashMap::<ID, X>::new();
while let Some(next) = seq.next_element::<X>()? {
map.insert(next.get_id(), next);
}
Ok(map)
}
}