1use serde::de::Error;
2
3#[cfg(not(feature = "std"))]
4use core::marker::PhantomData;
5#[cfg(feature = "std")]
6use std::marker::PhantomData;
7
8#[cfg(not(feature = "std"))]
9use alloc::vec::Vec;
10
11use crate::prelude::*;
12
13use crate::graph::Node;
14use crate::graph::{Edge, IndexType};
15use crate::serde_utils::CollectSeqWithLength;
16use crate::serde_utils::MappedSequenceVisitor;
17use crate::serde_utils::{FromDeserialized, IntoSerializable};
18use crate::EdgeType;
19
20use super::{EdgeIndex, NodeIndex};
21use serde::{Deserialize, Deserializer, Serialize, Serializer};
22
23#[derive(Serialize)]
47#[serde(rename = "Graph")]
48#[serde(bound(serialize = "N: Serialize, E: Serialize, Ix: IndexType + Serialize"))]
49pub struct SerGraph<'a, N: 'a, E: 'a, Ix: 'a + IndexType> {
50 #[serde(serialize_with = "ser_graph_nodes")]
51 nodes: &'a [Node<N, Ix>],
52 node_holes: &'a [NodeIndex<Ix>],
53 edge_property: EdgeProperty,
54 #[serde(serialize_with = "ser_graph_edges")]
55 edges: &'a [Edge<E, Ix>],
56}
57
58#[derive(Deserialize)]
61#[serde(rename = "Graph")]
62#[serde(bound(
63 deserialize = "N: Deserialize<'de>, E: Deserialize<'de>, Ix: IndexType + Deserialize<'de>"
64))]
65pub struct DeserGraph<N, E, Ix> {
66 #[serde(deserialize_with = "deser_graph_nodes")]
67 nodes: Vec<Node<N, Ix>>,
68 #[serde(deserialize_with = "deser_graph_node_holes")]
69 #[allow(unused)]
70 #[serde(default = "Vec::new")]
71 node_holes: Vec<NodeIndex<Ix>>,
72 edge_property: EdgeProperty,
73 #[serde(deserialize_with = "deser_graph_edges")]
74 edges: Vec<Edge<E, Ix>>,
75}
76
77impl<Ix> Serialize for NodeIndex<Ix>
78where
79 Ix: IndexType + Serialize,
80{
81 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
82 where
83 S: Serializer,
84 {
85 self.0.serialize(serializer)
86 }
87}
88
89impl<'de, Ix> Deserialize<'de> for NodeIndex<Ix>
90where
91 Ix: IndexType + Deserialize<'de>,
92{
93 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
94 where
95 D: Deserializer<'de>,
96 {
97 Ok(NodeIndex(Ix::deserialize(deserializer)?))
98 }
99}
100
101impl<Ix> Serialize for EdgeIndex<Ix>
102where
103 Ix: IndexType + Serialize,
104{
105 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
106 where
107 S: Serializer,
108 {
109 self.0.serialize(serializer)
110 }
111}
112
113impl<'de, Ix> Deserialize<'de> for EdgeIndex<Ix>
114where
115 Ix: IndexType + Deserialize<'de>,
116{
117 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
118 where
119 D: Deserializer<'de>,
120 {
121 Ok(EdgeIndex(Ix::deserialize(deserializer)?))
122 }
123}
124
125#[derive(Serialize, Deserialize)]
126#[serde(rename_all = "lowercase")]
127#[derive(Debug)]
128pub enum EdgeProperty {
129 Undirected,
130 Directed,
131}
132
133impl EdgeProperty {
134 pub fn is_directed(&self) -> bool {
135 match *self {
136 EdgeProperty::Directed => true,
137 EdgeProperty::Undirected => false,
138 }
139 }
140}
141
142impl<Ty> From<PhantomData<Ty>> for EdgeProperty
143where
144 Ty: EdgeType,
145{
146 fn from(_: PhantomData<Ty>) -> Self {
147 if Ty::is_directed() {
148 EdgeProperty::Directed
149 } else {
150 EdgeProperty::Undirected
151 }
152 }
153}
154
155impl<Ty> FromDeserialized for PhantomData<Ty>
156where
157 Ty: EdgeType,
158{
159 type Input = EdgeProperty;
160 fn from_deserialized<E2>(input: Self::Input) -> Result<Self, E2>
161 where
162 E2: Error,
163 {
164 if input.is_directed() != Ty::is_directed() {
165 Err(E2::custom(format_args!(
166 "graph edge property mismatch, \
167 expected {:?}, found {:?}",
168 EdgeProperty::from(PhantomData::<Ty>),
169 input
170 )))
171 } else {
172 Ok(PhantomData)
173 }
174 }
175}
176
177fn ser_graph_nodes<S, N, Ix>(nodes: &&[Node<N, Ix>], serializer: S) -> Result<S::Ok, S::Error>
178where
179 S: Serializer,
180 N: Serialize,
181 Ix: Serialize + IndexType,
182{
183 serializer.collect_seq_exact(nodes.iter().map(|node| &node.weight))
184}
185
186fn ser_graph_edges<S, E, Ix>(edges: &&[Edge<E, Ix>], serializer: S) -> Result<S::Ok, S::Error>
187where
188 S: Serializer,
189 E: Serialize,
190 Ix: Serialize + IndexType,
191{
192 serializer.collect_seq_exact(
193 edges
194 .iter()
195 .map(|edge| Some((edge.source(), edge.target(), &edge.weight))),
196 )
197}
198
199fn deser_graph_nodes<'de, D, N, Ix>(deserializer: D) -> Result<Vec<Node<N, Ix>>, D::Error>
200where
201 D: Deserializer<'de>,
202 N: Deserialize<'de>,
203 Ix: IndexType + Deserialize<'de>,
204{
205 deserializer.deserialize_seq(MappedSequenceVisitor::new(|n| {
206 Ok(Node {
207 weight: n,
208 next: [EdgeIndex::end(); 2],
209 })
210 }))
211}
212
213fn deser_graph_node_holes<'de, D, Ix>(deserializer: D) -> Result<Vec<NodeIndex<Ix>>, D::Error>
214where
215 D: Deserializer<'de>,
216 Ix: IndexType + Deserialize<'de>,
217{
218 deserializer.deserialize_seq(
219 MappedSequenceVisitor::<NodeIndex<Ix>, NodeIndex<Ix>, _>::new(|_| {
220 Err("Graph can not have holes in the node set, found non-empty node_holes")
221 }),
222 )
223}
224
225fn deser_graph_edges<'de, D, N, Ix>(deserializer: D) -> Result<Vec<Edge<N, Ix>>, D::Error>
226where
227 D: Deserializer<'de>,
228 N: Deserialize<'de>,
229 Ix: IndexType + Deserialize<'de>,
230{
231 deserializer.deserialize_seq(MappedSequenceVisitor::<
232 Option<(NodeIndex<Ix>, NodeIndex<Ix>, N)>,
233 _,
234 _,
235 >::new(|x| {
236 if let Some((i, j, w)) = x {
237 Ok(Edge {
238 weight: w,
239 node: [i, j],
240 next: [EdgeIndex::end(); 2],
241 })
242 } else {
243 Err("Graph can not have holes in the edge set, found None, expected edge")
244 }
245 }))
246}
247
248impl<'a, N, E, Ty, Ix> IntoSerializable for &'a Graph<N, E, Ty, Ix>
249where
250 Ix: IndexType,
251 Ty: EdgeType,
252{
253 type Output = SerGraph<'a, N, E, Ix>;
254 fn into_serializable(self) -> Self::Output {
255 SerGraph {
256 nodes: &self.nodes,
257 node_holes: &[],
258 edges: &self.edges,
259 edge_property: EdgeProperty::from(PhantomData::<Ty>),
260 }
261 }
262}
263
264impl<N, E, Ty, Ix> Serialize for Graph<N, E, Ty, Ix>
266where
267 Ty: EdgeType,
268 Ix: IndexType + Serialize,
269 N: Serialize,
270 E: Serialize,
271{
272 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
273 where
274 S: Serializer,
275 {
276 self.into_serializable().serialize(serializer)
277 }
278}
279
280pub fn invalid_node_err<E>(node_index: usize, len: usize) -> E
281where
282 E: Error,
283{
284 E::custom(format_args!(
285 "invalid value: node index `{}` does not exist in graph \
286 with node bound {}",
287 node_index, len
288 ))
289}
290
291pub fn invalid_length_err<Ix, E>(node_or_edge: &str, len: usize) -> E
292where
293 E: Error,
294 Ix: IndexType,
295{
296 E::custom(format_args!(
297 "invalid size: graph {} count {} exceeds index type maximum {}",
298 node_or_edge,
299 len,
300 <Ix as IndexType>::max().index()
301 ))
302}
303
304impl<'a, N, E, Ty, Ix> FromDeserialized for Graph<N, E, Ty, Ix>
305where
306 Ix: IndexType,
307 Ty: EdgeType,
308{
309 type Input = DeserGraph<N, E, Ix>;
310 fn from_deserialized<E2>(input: Self::Input) -> Result<Self, E2>
311 where
312 E2: Error,
313 {
314 let ty = PhantomData::<Ty>::from_deserialized(input.edge_property)?;
315 let nodes = input.nodes;
316 let edges = input.edges;
317 if nodes.len() >= <Ix as IndexType>::max().index() {
318 Err(invalid_length_err::<Ix, _>("node", nodes.len()))?
319 }
320
321 if edges.len() >= <Ix as IndexType>::max().index() {
322 Err(invalid_length_err::<Ix, _>("edge", edges.len()))?
323 }
324
325 let mut gr = Graph {
326 nodes: nodes,
327 edges: edges,
328 ty: ty,
329 };
330 let nc = gr.node_count();
331 gr.link_edges()
332 .map_err(|i| invalid_node_err(i.index(), nc))?;
333 Ok(gr)
334 }
335}
336
337impl<'de, N, E, Ty, Ix> Deserialize<'de> for Graph<N, E, Ty, Ix>
339where
340 Ty: EdgeType,
341 Ix: IndexType + Deserialize<'de>,
342 N: Deserialize<'de>,
343 E: Deserialize<'de>,
344{
345 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
346 where
347 D: Deserializer<'de>,
348 {
349 Self::from_deserialized(DeserGraph::deserialize(deserializer)?)
350 }
351}