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