rapx/analysis/core/api_dependency/graph/
serialize.rs1use super::dep_edge::DepEdge;
2use super::dep_node::DepNode;
3use crate::analysis::core::api_dependency::ApiDependencyGraph;
4use serde::{
5 ser::{SerializeMap, SerializeSeq},
6 Serialize,
7};
8use std::path::Path;
9
10#[derive(Serialize, Debug)]
11struct NodeInfo {
12 id: usize,
13 kind: String,
14 path: String,
15 args: Vec<String>,
16}
17
18#[derive(Serialize, Debug)]
19struct EdgeInfo {
20 id: usize,
21 kind: String,
22 from: usize,
23 to: usize,
24}
25
26impl<'tcx> ApiDependencyGraph<'tcx> {
27 pub fn dump_to_json(&self, path: impl AsRef<Path>) -> std::io::Result<()> {
28 let file = std::fs::File::create(path)?;
29 serde_json::to_writer_pretty(file, self)?;
30 Ok(())
31 }
32}
33
34impl<'tcx> Serialize for ApiDependencyGraph<'tcx> {
35 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
36 where
37 S: serde::Serializer,
38 {
39 let mut map = serializer.serialize_map(Some(2))?;
40 let mut nodes = Vec::new();
41 for index in self.graph.node_indices() {
42 let node_info = match self.graph[index] {
43 DepNode::Api(fn_did, args) => NodeInfo {
44 id: index.index(),
45 kind: "api".to_owned(),
46 path: self.tcx.def_path_str(fn_did),
47 args: args.iter().map(|arg| arg.to_string()).collect(),
48 },
49 DepNode::Ty(ty) => NodeInfo {
50 id: index.index(),
51 kind: "type".to_owned(),
52 path: ty.ty().to_string(),
53 args: vec![],
54 },
55 };
56 nodes.push(node_info);
57 }
58 let mut edges = Vec::new();
59 for index in self.graph.edge_indices() {
60 let kind = match self.graph[index] {
61 DepEdge::Arg(no) => "arg".to_owned(),
62 DepEdge::Ret => "ret".to_owned(),
63 DepEdge::Transform(kind) => format!("transform({})", kind),
64 };
65 let (from, to) = self.graph.edge_endpoints(index).unwrap();
66 let (from, to) = (from.index(), to.index());
67 edges.push(EdgeInfo {
68 id: index.index(),
69 kind: "arg".to_owned(),
70 from,
71 to,
72 });
73 }
74 map.serialize_entry("nodes", &nodes)?;
75 map.serialize_entry("edges", &edges)?;
76 map.end()
77 }
78}