use std::fs;
use std::io;
use std::path::Path;
use serde::{Deserialize, Serialize};
use super::def::Def;
use super::edge::{Edge, EdgesByKind, HeuristicByTier};
use super::ordered::Percent1;
use super::paths::{atomic_write_json, graph_json_path};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Stats {
pub def_count: usize,
pub file_count: usize,
pub edges_by_kind: EdgesByKind,
pub ambiguous_count: usize,
pub ambiguous_pct: Percent1,
pub unresolved_external_count: usize,
#[serde(default)]
pub heuristic_edge_count: usize,
#[serde(default)]
pub test_def_count: usize,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ts: Option<crate::tsgraph::TsStats>,
#[serde(default)]
pub heuristic_by_tier: HeuristicByTier,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GraphName {
pub name: String,
pub kind: String,
pub file: String,
pub line: usize,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub owner: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GraphUnit {
pub id: String,
pub name: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub refs: Vec<String>,
#[serde(default, skip_serializing_if = "is_not_test")]
pub test: bool,
}
fn is_not_test(b: &bool) -> bool {
!*b
}
pub const GRAPH_SCHEMA_VERSION: u32 = 3;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Graph {
pub schema_version: u32,
pub built_at_head: Option<String>,
pub defs: Vec<Def>,
pub edges: Vec<Edge>,
pub stats: Stats,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub names: Vec<GraphName>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub units: Vec<GraphUnit>,
}
pub fn read_graph(root: &Path) -> Option<Graph> {
let text = fs::read_to_string(graph_json_path(root)).ok()?;
serde_json::from_str(&text).ok()
}
pub(crate) fn write_graph(root: &Path, graph: &Graph) -> io::Result<()> {
atomic_write_json(&graph_json_path(root), graph)
}