1use serde::de::Error;
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3
4use std::marker::PhantomData;
5
6use crate::prelude::*;
7
8use crate::graph::Node;
9use crate::graph::{Edge, IndexType};
10use crate::serde_utils::CollectSeqWithLength;
11use crate::serde_utils::MappedSequenceVisitor;
12use crate::serde_utils::{FromDeserialized, IntoSerializable};
13use crate::stable_graph::StableGraph;
14use crate::util::rev;
15use crate::visit::NodeIndexable;
16use crate::EdgeType;
17
18use super::super::serialization::{invalid_length_err, invalid_node_err, EdgeProperty};
19
20#[derive(Serialize)]
23#[serde(rename = "Graph")]
24#[serde(bound(serialize = "N: Serialize, E: Serialize, Ix: IndexType + Serialize"))]
25pub struct SerStableGraph<'a, N: 'a, E: 'a, Ix: 'a + IndexType> {
26 nodes: Somes<&'a [Node<Option<N>, Ix>]>,
27 node_holes: Holes<&'a [Node<Option<N>, Ix>]>,
28 edge_property: EdgeProperty,
29 #[serde(serialize_with = "ser_stable_graph_edges")]
30 edges: &'a [Edge<Option<E>, Ix>],
31}
32
33#[derive(Deserialize)]
36#[serde(rename = "Graph")]
37#[serde(bound(
38 deserialize = "N: Deserialize<'de>, E: Deserialize<'de>, Ix: IndexType + Deserialize<'de>"
39))]
40pub struct DeserStableGraph<N, E, Ix> {
41 #[serde(deserialize_with = "deser_stable_graph_nodes")]
42 nodes: Vec<Node<Option<N>, Ix>>,
43 #[serde(default = "Vec::new")]
44 node_holes: Vec<NodeIndex<Ix>>,
45 edge_property: EdgeProperty,
46 #[serde(deserialize_with = "deser_stable_graph_edges")]
47 edges: Vec<Edge<Option<E>, Ix>>,
48}
49
50struct Somes<T>(usize, T);
52
53impl<'a, N, Ix> Serialize for Somes<&'a [Node<Option<N>, Ix>]>
54where
55 N: Serialize,
56{
57 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58 where
59 S: Serializer,
60 {
61 serializer.collect_seq_with_length(
62 self.0,
63 self.1.iter().filter_map(|node| node.weight.as_ref()),
64 )
65 }
66}
67
68struct Holes<T>(usize, T);
70
71impl<'a, N, Ix> Serialize for Holes<&'a [Node<Option<N>, Ix>]>
72where
73 Ix: Serialize + IndexType,
74{
75 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
76 where
77 S: Serializer,
78 {
79 serializer.collect_seq_with_length(
80 self.0,
81 self.1.iter().enumerate().filter_map(|(i, node)| {
82 if node.weight.is_none() {
83 Some(NodeIndex::<Ix>::new(i))
84 } else {
85 None
86 }
87 }),
88 )
89 }
90}
91
92fn ser_stable_graph_edges<S, E, Ix>(
93 edges: &&[Edge<Option<E>, Ix>],
94 serializer: S,
95) -> Result<S::Ok, S::Error>
96where
97 S: Serializer,
98 E: Serialize,
99 Ix: Serialize + IndexType,
100{
101 serializer.collect_seq_exact(edges.iter().map(|edge| {
102 edge.weight
103 .as_ref()
104 .map(|w| (edge.source(), edge.target(), w))
105 }))
106}
107
108fn deser_stable_graph_nodes<'de, D, N, Ix>(
109 deserializer: D,
110) -> Result<Vec<Node<Option<N>, Ix>>, D::Error>
111where
112 D: Deserializer<'de>,
113 N: Deserialize<'de>,
114 Ix: IndexType + Deserialize<'de>,
115{
116 deserializer.deserialize_seq(MappedSequenceVisitor::new(|n| {
117 Ok(Node {
118 weight: Some(n),
119 next: [EdgeIndex::end(); 2],
120 })
121 }))
122}
123
124fn deser_stable_graph_edges<'de, D, N, Ix>(
125 deserializer: D,
126) -> Result<Vec<Edge<Option<N>, Ix>>, D::Error>
127where
128 D: Deserializer<'de>,
129 N: Deserialize<'de>,
130 Ix: IndexType + Deserialize<'de>,
131{
132 deserializer.deserialize_seq(MappedSequenceVisitor::<
133 Option<(NodeIndex<Ix>, NodeIndex<Ix>, N)>,
134 _,
135 _,
136 >::new(|x| {
137 if let Some((i, j, w)) = x {
138 Ok(Edge {
139 weight: Some(w),
140 node: [i, j],
141 next: [EdgeIndex::end(); 2],
142 })
143 } else {
144 Ok(Edge {
145 weight: None,
146 node: [NodeIndex::end(); 2],
147 next: [EdgeIndex::end(); 2],
148 })
149 }
150 }))
151}
152
153impl<'a, N, E, Ty, Ix> IntoSerializable for &'a StableGraph<N, E, Ty, Ix>
154where
155 Ix: IndexType,
156 Ty: EdgeType,
157{
158 type Output = SerStableGraph<'a, N, E, Ix>;
159 fn into_serializable(self) -> Self::Output {
160 let nodes = &self.raw_nodes()[..self.node_bound()];
161 let node_count = self.node_count();
162 let hole_count = nodes.len() - node_count;
163 let edges = &self.raw_edges()[..self.edge_bound()];
164 SerStableGraph {
165 nodes: Somes(node_count, nodes),
166 node_holes: Holes(hole_count, nodes),
167 edges: edges,
168 edge_property: EdgeProperty::from(PhantomData::<Ty>),
169 }
170 }
171}
172
173impl<N, E, Ty, Ix> Serialize for StableGraph<N, E, Ty, Ix>
175where
176 Ty: EdgeType,
177 Ix: IndexType + Serialize,
178 N: Serialize,
179 E: Serialize,
180{
181 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
182 where
183 S: Serializer,
184 {
185 self.into_serializable().serialize(serializer)
186 }
187}
188
189impl<'a, N, E, Ty, Ix> FromDeserialized for StableGraph<N, E, Ty, Ix>
190where
191 Ix: IndexType,
192 Ty: EdgeType,
193{
194 type Input = DeserStableGraph<N, E, Ix>;
195 fn from_deserialized<E2>(input: Self::Input) -> Result<Self, E2>
196 where
197 E2: Error,
198 {
199 let ty = PhantomData::<Ty>::from_deserialized(input.edge_property)?;
200 let mut nodes = input.nodes;
201 let node_holes = input.node_holes;
202 let edges = input.edges;
203 if edges.len() >= <Ix as IndexType>::max().index() {
204 Err(invalid_length_err::<Ix, _>("edge", edges.len()))?
205 }
206
207 let mut offset = node_holes.len();
209 let node_bound = node_holes.len() + nodes.len();
210 for hole_pos in rev(node_holes) {
211 offset -= 1;
212 if hole_pos.index() >= node_bound {
213 Err(invalid_node_err(hole_pos.index(), node_bound))?;
214 }
215 let insert_pos = hole_pos.index() - offset;
216 nodes.insert(
217 insert_pos,
218 Node {
219 weight: None,
220 next: [EdgeIndex::end(); 2],
221 },
222 );
223 }
224
225 if nodes.len() >= <Ix as IndexType>::max().index() {
226 Err(invalid_length_err::<Ix, _>("node", nodes.len()))?
227 }
228
229 let node_bound = nodes.len();
230 let mut sgr = StableGraph {
231 g: Graph {
232 nodes: nodes,
233 edges: edges,
234 ty: ty,
235 },
236 node_count: 0,
237 edge_count: 0,
238 free_edge: EdgeIndex::end(),
239 free_node: NodeIndex::end(),
240 };
241 sgr.link_edges()
242 .map_err(|i| invalid_node_err(i.index(), node_bound))?;
243 Ok(sgr)
244 }
245}
246
247impl<'de, N, E, Ty, Ix> Deserialize<'de> for StableGraph<N, E, Ty, Ix>
249where
250 Ty: EdgeType,
251 Ix: IndexType + Deserialize<'de>,
252 N: Deserialize<'de>,
253 E: Deserialize<'de>,
254{
255 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
256 where
257 D: Deserializer<'de>,
258 {
259 Self::from_deserialized(DeserStableGraph::deserialize(deserializer)?)
260 }
261}
262
263#[test]
264fn test_from_deserialized_with_holes() {
265 use crate::graph::node_index;
266 use crate::stable_graph::StableUnGraph;
267 use itertools::assert_equal;
268 use serde::de::value::Error as SerdeError;
269
270 let input = DeserStableGraph::<_, (), u32> {
271 nodes: vec![
272 Node {
273 weight: Some(1),
274 next: [EdgeIndex::end(); 2],
275 },
276 Node {
277 weight: Some(4),
278 next: [EdgeIndex::end(); 2],
279 },
280 Node {
281 weight: Some(5),
282 next: [EdgeIndex::end(); 2],
283 },
284 ],
285 node_holes: vec![node_index(0), node_index(2), node_index(3), node_index(6)],
286 edges: vec![],
287 edge_property: EdgeProperty::Undirected,
288 };
289 let graph = StableUnGraph::from_deserialized::<SerdeError>(input).unwrap();
290
291 assert_eq!(graph.node_count(), 3);
292 assert_equal(
293 graph.raw_nodes().iter().map(|n| n.weight.as_ref().cloned()),
294 vec![None, Some(1), None, None, Some(4), Some(5), None],
295 );
296}