use serde::de::{DeserializeOwned, Error};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use crate::{EdgeExt, Id, Key, NodeExt, Typed};
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(bound = "K: DeserializeOwned + Serialize")]
#[serde(try_from = "Value")]
#[serde(into = "Value")]
pub struct AnyWeight<K: Key> {
id: K,
ty: String,
data: Map<String, Value>,
}
impl<K: DeserializeOwned + Key> TryFrom<Value> for AnyWeight<K> {
type Error = serde_json::Error;
fn try_from(value: Value) -> Result<Self, Self::Error> {
match value {
Value::Object(o) => {
if o.len() != 1 {
return Err(serde_json::Error::custom("expected type in object"));
}
let (ty, data) = o.into_iter().next().unwrap();
let data = if let Value::Object(o) = data {
o
} else {
return Err(serde_json::Error::custom("expected data to be object"));
};
let id_value = data
.get("id")
.ok_or_else(|| serde_json::Error::custom("expected id field"))?;
let id = serde_json::from_value(id_value.clone())?;
Ok(AnyWeight { id, ty, data })
}
_ => Err(serde_json::Error::custom("expected object")),
}
}
}
impl<K: Serialize + Key> Into<Value> for AnyWeight<K> {
fn into(self) -> Value {
let id = serde_json::to_value(self.id).unwrap();
let mut out_data = self.data;
out_data.insert("id".to_string(), id);
let mut object = Map::new();
object.insert(self.ty, Value::Object(out_data));
Value::Object(object)
}
}
impl<K: Key> PartialEq<String> for AnyWeight<K> {
fn eq(&self, other: &String) -> bool {
&self.ty == other
}
}
impl<NK: Key> NodeExt<NK> for AnyWeight<NK> {}
impl<NK: Key> EdgeExt<NK> for AnyWeight<NK> {}
impl<NK: Key> Id<NK> for AnyWeight<NK> {
fn get_id(&self) -> NK {
self.id
}
fn set_id(&mut self, new_id: NK) {
self.id = new_id;
}
}
impl<NK: Key> Typed for AnyWeight<NK> {
type Type = String;
fn get_type(&self) -> Self::Type {
self.ty.clone()
}
}