1use crate::graphs::ModuleParentGraph;
18use meshed::graph::node::Node;
19use meshed::graph::Inverted;
20use std::collections::HashSet;
21
22use meshed::prelude::*;
23use serde::ser::SerializeMap;
24use serde::{Serialize, Serializer};
25
26use std::marker::PhantomData;
27use webpack_stats::chunk::ChunkId;
28use webpack_stats::import::ImportType;
29
30pub struct GraphSerialization<T, K> {
31 graph: T,
32 kind: PhantomData<K>,
33}
34
35impl<T, K> GraphSerialization<T, K> {
36 pub fn new<Kind>(graph: T) -> GraphSerialization<T, Kind> {
37 GraphSerialization {
38 graph,
39 kind: Default::default(),
40 }
41 }
42}
43
44pub struct NodeEdge;
45
46type ModuleEdgeSer = GraphSerialization<Inverted<ModuleParentGraph>, NodeEdge>;
47
48impl Serialize for ModuleEdgeSer {
49 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
50 where
51 S: Serializer,
52 {
53 let mut map_serializer = serializer.serialize_map(Some(2))?;
54 map_serializer.serialize_key("nodes")?;
55
56 struct NodeSerializer(Node<ModuleParentGraph>);
57
58 impl Serialize for NodeSerializer {
59 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60 where
61 S: Serializer,
62 {
63 let mut map = serializer.serialize_map(Some(3))?;
64 map.serialize_key("id")?;
65 map.serialize_value(&self.0.get_id().to_string())?;
66 if let Some(value) = self.0.get_annotation::<ChunkId>() {
67 map.serialize_key("chunk")?;
68 map.serialize_value(&value.0)?;
69 } else {
70 map.serialize_key("chunk")?;
71 map.serialize_value(&None as &Option<()>)?;
72 }
73
74 map.serialize_key("label")?;
75 map.serialize_value(&self.0.label().to_string())?;
76 map.end()
77 }
78 }
79
80 let nodes = self
81 .graph
82 .inner()
83 .all_nodes()
84 .map(NodeSerializer)
85 .collect::<Vec<_>>();
86
87 map_serializer.serialize_value(&nodes)?;
88
89 struct EdgeSerializer(meshed::graph::edge::Edge<ModuleParentGraph>);
90
91 impl Serialize for EdgeSerializer {
92 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: Serializer,
95 {
96 let mut map = serializer.serialize_map(Some(4))?;
97
98 map.serialize_key("source")?;
99 map.serialize_value(self.0.origin.get_id().0.as_ref())?;
100 map.serialize_key("target")?;
101 map.serialize_value(self.0.target.get_id().0.as_ref())?;
102 map.serialize_key("async")?;
103 map.serialize_value(&matches!(
104 self.0.meta.as_ref().0,
105 ImportType::RequireContext | ImportType::Import | ImportType::ImportDynamic
106 ))?;
107
108 map.serialize_key("importer")?;
109 map.serialize_value(&self.0.meta.as_ref().1 .0)?;
110
111 map.end()
112 }
113 }
114 let mut seen_set = HashSet::new();
115 let edges = self
116 .graph
117 .inner()
118 .all_edges()
119 .filter(|edge| {
120 if seen_set.contains(&edge.get_id()) {
121 false
122 } else {
123 seen_set.insert(edge.get_id());
124 true
125 }
126 })
127 .map(EdgeSerializer)
128 .collect::<Vec<_>>();
129
130 map_serializer.serialize_key("edges")?;
131 map_serializer.serialize_value(&edges)?;
132 map_serializer.end()
133 }
134}