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