yaxpeax_core/
serialize.rs

1use serde::de;
2use std::fmt;
3use serde::de::{MapAccess, SeqAccess, Deserializer, Visitor};
4use std::cell::Cell;
5use serde::{Serialize, Deserialize, Serializer};
6use serde::ser::SerializeStruct;
7
8use yaxpeax_arch::Address;
9use petgraph::graphmap::{GraphMap, NodeTrait};
10
11use std::hash::Hash;
12use std::collections::HashMap;
13
14pub struct GraphSerializer<'a, A> {
15    graph: &'a GraphMap<A, (), petgraph::Directed>
16}
17
18impl <'a, A: NodeTrait + Hash + Serialize> GraphSerializer<'a, A> {
19    pub fn from(graph: &'a GraphMap<A, (), petgraph::Directed>) -> GraphSerializer<'a, A> {
20        GraphSerializer { graph }
21    }
22}
23
24impl <'a, A: NodeTrait + Hash + Serialize> Serialize for GraphSerializer<'a, A> {
25    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
26        let mut struc = serializer.serialize_struct("GraphMap<A>", 2)?;
27        let edgevec: Vec<(A, A)> = self.graph.all_edges().map(|(a, b, _)| (a.to_owned(), b.to_owned())).collect();
28        struc.serialize_field("edges", &edgevec)?;
29        let nodevec: Vec<A> = self.graph.nodes().map(|n| n.to_owned()).collect();
30        struc.serialize_field("nodes", &nodevec)?;
31        struc.end()
32    }
33}
34
35pub struct GraphDeserializer<A> {
36    graph: GraphMap<A, (), petgraph::Directed>
37}
38
39impl <A> GraphDeserializer<A> {
40    pub fn into_inner(self) -> GraphMap<A, (), petgraph::Directed> {
41        self.graph
42    }
43}
44
45#[derive(Deserialize)]
46#[serde(field_identifier, rename_all = "lowercase")]
47enum Field { Edges, Nodes }
48
49struct GraphVisitor<A> {
50    _marker: std::marker::PhantomData<A>
51}
52
53impl <A: Hash + Ord + Copy + Clone> GraphVisitor<A> {
54    pub fn new() -> Self {
55        GraphVisitor {
56            _marker: std::marker::PhantomData
57        }
58    }
59}
60
61impl <'de, A: Address + Hash> Visitor<'de> for GraphVisitor<A> {
62    type Value = GraphDeserializer<A>;
63
64    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
65        formatter.write_str("struct GraphMap<A, (), Directed>")
66    }
67
68    fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
69    where
70        V: SeqAccess<'de>
71    {
72        let mut graph = GraphMap::new();
73        let edges: Vec<(A, A)> = seq.next_element()?
74            .ok_or_else(|| de::Error::invalid_length(0, &self))?;
75        for (start, end) in edges.into_iter() {
76            graph.add_edge(start, end, ());
77        }
78        let nodes: Vec<A> = seq.next_element()?
79            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
80        for node in nodes.into_iter() {
81            graph.add_node(node);
82        }
83
84        Ok(GraphDeserializer { graph })
85    }
86
87    fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
88    where
89        V: MapAccess<'de>,
90    {
91        let mut graph = GraphMap::new();
92        let mut edges = None;
93        let mut nodes = None;
94        while let Some(key) = map.next_key()? {
95            match key {
96                Field::Edges => {
97                    if edges.is_some() {
98                        return Err(de::Error::duplicate_field("edges"));
99                    }
100                    edges = Some(map.next_value()?);
101                },
102                Field::Nodes => {
103                    if nodes.is_some() {
104                        return Err(de::Error::duplicate_field("nodes"));
105                    }
106                    nodes = Some(map.next_value()?);
107                }
108            }
109        }
110        let edges: Vec<(A, A)> = edges.ok_or_else(|| de::Error::missing_field("edges"))?;
111        for (start, end) in edges.into_iter() {
112            graph.add_edge(start, end, ());
113        }
114        let nodes: Vec<A> = nodes.ok_or_else(|| de::Error::missing_field("nodes"))?;
115        for node in nodes.into_iter() {
116            graph.add_node(node);
117        }
118
119        Ok(GraphDeserializer { graph })
120    }
121}
122
123impl<'de, A: Address + Hash> Deserialize<'de> for GraphDeserializer<A> {
124    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
125    where
126        D: Deserializer<'de>,
127    {
128        const FIELDS: &'static [&'static str] = &["edges", "nodes"];
129        deserializer.deserialize_struct(
130            "GraphMap<A, (), Directed>",
131            FIELDS,
132            GraphVisitor::new()
133        )
134    }
135}
136
137pub trait Memoable: Sized {
138    type Out: Sized + Serialize + for<'de> Deserialize<'de>;
139
140    fn memoize(&self, memos: &HashMap<Self, u32>) -> Self::Out;
141    fn dememoize(idx: u32, memos: &[Self::Out], dememoized: &mut HashMap<u32, Self>) -> Self;
142}
143
144pub struct Memos<T: Hash + PartialEq + Eq> {
145    pub node_ids: HashMap<T, u32>,
146}
147
148impl <T: Hash + PartialEq + Eq> Memos<T> {
149    pub fn new() -> Memos<T> {
150        Memos {
151            node_ids: HashMap::new(),
152        }
153    }
154
155    pub fn id_of(&mut self, t: T) -> u32 {
156        let next = self.node_ids.len();
157        *self.node_ids.entry(t).or_insert_with(|| {
158            next as u32 // TODO: error on overflow
159        })
160    }
161}
162
163pub struct MemoizingSerializer<'a, 'b, T: ?Sized, M: Hash + PartialEq + Eq> {
164    pub memos: Cell<Option<&'a mut Memos<M>>>,
165    pub inner: &'b T,
166}
167
168impl <'a, 'b, T: ?Sized, M: Hash + PartialEq + Eq> MemoizingSerializer<'a, 'b, T, M> {
169    pub fn new(memos: &'a mut Memos<M>, inner: &'b T) -> Self {
170        MemoizingSerializer { memos: Cell::new(Some(memos)), inner }
171    }
172
173    pub fn with_memos<R, F: FnOnce(&mut Memos<M>) -> R>(&self, f: F) -> R {
174        let memo_ref = if let Some(memo_ref) = self.memos.take() {
175            memo_ref
176        } else {
177            panic!("implementation error: attempted to mutably use memos from two locations at once. this should be impossible!");
178        };
179        let res = f(memo_ref);
180        self.memos.set(Some(memo_ref));
181        res
182    }
183
184    pub fn id_of(&self, memo: M) -> u32 {
185        self.with_memos(|memos| memos.id_of(memo))
186    }
187}
188