use super::*;
use serde::{
de::Deserialize,
ser::{Serialize, SerializeSeq, SerializeStruct},
};
#[derive(Debug, Serialize, Deserialize)]
pub struct GraphSerializer<NodeT>
where
NodeT: NodeEnum,
{
ctx_id: Uuid,
nodes: Vec<(NodeIndex, NodeT)>,
}
impl<NodeT, Arena> From<Graph<NodeT, Arena>> for GraphSerializer<NodeT>
where
NodeT: NodeEnum,
Arena: CateArena<V = NodeT, D = NodeT::Discriminant>,
{
fn from(value: Graph<NodeT, Arena>) -> GraphSerializer<NodeT> {
GraphSerializer {
ctx_id: value.ctx_id,
nodes: Vec::from_iter(value.into_iter()),
}
}
}
struct NodeSerialize<'a, NodeT, Arena>(Arena::Iter<'a>)
where
NodeT: NodeEnum + Serialize + 'static,
Arena: CateArena<V = NodeT, D = NodeT::Discriminant>;
impl<'a, NodeT, Arena> Serialize for NodeSerialize<'a, NodeT, Arena>
where
NodeT: NodeEnum + Serialize + 'static,
Arena: CateArena<V = NodeT, D = NodeT::Discriminant>,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut nodes = serializer.serialize_seq(Some(self.0.len()))?;
for (i, n) in self.0.clone() {
nodes.serialize_element(&(i, n))?;
}
nodes.end()
}
}
impl<NodeT, Arena> Serialize for Graph<NodeT, Arena>
where
NodeT: NodeEnum + Serialize + 'static,
Arena: CateArena<V = NodeT, D = NodeT::Discriminant>,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut graph = serializer.serialize_struct("Graph", 2)?;
graph.serialize_field("ctx_id", &self.ctx_id)?;
graph.serialize_field("nodes", &NodeSerialize::<NodeT, Arena>(self.iter()))?;
graph.end()
}
}
pub fn deserialize_graph<'de, NodeT: NodeEnum + Deserialize<'de>>(
input: GraphSerializer<NodeT>,
) -> (Context, Graph<NodeT>) {
let cnt = input.nodes.iter().map(|(idx, _)| idx.0).max().unwrap_or_else(|| 0);
let ctx = Context::from_id(input.ctx_id, cnt);
let graph = Graph::do_deserialize(&ctx, input.nodes);
(ctx, graph)
}