use field_collex::{Collexetable, FieldCollex, FieldValue};
use field_collex::collex::se::{FieldCollexSerdeHelper, FieldCollexSerdeWrapper};
use serde::{Deserialize, Deserializer};
use serde::de::Error;
use crate::{Id, IdMap, OrdIdMap};
use crate::pair::Pair;
impl<'de, K, O, T> Deserialize<'de> for OrdIdMap<K, O, T>
where
O: Collexetable<T> + Deserialize<'de>,
T: FieldValue + Deserialize<'de>,
K: Id + Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let collex_helper: FieldCollexSerdeHelper<Pair<K,O>, T> = FieldCollexSerdeWrapper::<Pair<K,O>, T>::deserialize(deserializer)
.map_err(|err|D::Error::custom(format!("反序列化 FieldCollexSerdeHelper 失败: {}", err)))?
.into();
let elements_len = collex_helper.elements.len();
let mut id_map = IdMap::<K, T>::with_id_capacity(elements_len);
for obj in collex_helper.elements.iter() {
let obj_id = obj.0; let t_value = obj.1.collexate(); id_map.insert_with_id(obj_id, t_value);
}
let collex = FieldCollex::with_elements(collex_helper.span, collex_helper.unit, collex_helper.elements)
.map_err(|e| D::Error::custom(format!("反序列化时创建 FieldCollex 失败: {}", e)))?;
Ok(Self {
id_map,
collex,
})
}
}
#[cfg(test)]
mod tests {
use field_collex::collex::se::{default_span, default_unit};
use serde::Serialize;
use super::*;
use serde_json;
use span_core::Span;
use crate::DefaultId;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TestO(pub u32);
pub type TestT = u32;
impl Collexetable<TestT> for TestO {
fn collexate(&self) -> TestT { self.0 }
fn collexate_ref(&self) -> &TestT {
&self.0
}
fn collexate_mut(&mut self) -> &mut TestT {
&mut self.0
}
}
#[test]
fn test_obj_allocator_serde_consistency() {
let span = Span::Finite(0u32..100u32);
let unit = 10u32;
let elements = vec![
Pair(DefaultId(1), TestO(10)),
Pair(DefaultId(2), TestO(20)),
Pair(DefaultId(3), TestO(30)),
];
let collex = FieldCollex::with_elements(span.clone(), unit.clone(), elements.clone())
.expect("构造 FieldCollex 失败");
let mut id_map = IdMap::<DefaultId, TestT>::with_capacity(elements.len());
for obj in &elements {
id_map.insert_with_id(obj.0, obj.1.collexate());
}
let original = OrdIdMap { id_map, collex };
let json = serde_json::to_string(&original).expect("序列化失败");
println!("序列化结果:\n{}", json);
let deserialized: OrdIdMap<DefaultId, TestO, TestT> = serde_json::from_str(&json)
.expect("反序列化失败");
let (id_map,collex) = deserialized.into_raw_parts();
assert_eq!(collex.span().clone(), default_span());
assert_eq!(collex.unit().clone(), default_unit::<u32>());
assert_eq!(collex
.into_iter()
.collect::<Vec<Pair<DefaultId, TestO>>>(), elements);
for obj in &elements {
let id = obj.0;
let expected_t = obj.1.collexate();
assert_eq!(id_map.inner.get(&id.as_u64()), Some(&expected_t));
}
assert!(id_map.inner.capacity() >= elements.len());
}
#[test]
fn test_obj_allocator_serde_empty() {
let span = Span::new_finite(0u32, 50u32);
let unit = 1032;
let collex = FieldCollex::new(span, unit)
.expect("构造空 FieldCollex 失败");
let original: OrdIdMap<DefaultId, TestO, TestT> = OrdIdMap {
id_map: IdMap::with_capacity(0),
collex,
};
let json = serde_json::to_string(&original).unwrap();
let deserialized: OrdIdMap<DefaultId, TestO, TestT> = serde_json::from_str(&json).unwrap();
assert!(deserialized.collex.is_empty());
assert!(deserialized.id_map.inner.is_empty());
}
}