cargo/core/compiler/
unit_graph.rs1use crate::core::compiler::Unit;
2use crate::core::compiler::{CompileKind, CompileMode};
3use crate::core::profiles::{Profile, UnitFor};
4use crate::core::{nightly_features_allowed, InternedString, PackageId, Target};
5use crate::util::CargoResult;
6use std::collections::HashMap;
7use std::io::Write;
8
9pub type UnitGraph<'a> = HashMap<Unit<'a>, Vec<UnitDep<'a>>>;
11
12#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
14pub struct UnitDep<'a> {
15 pub unit: Unit<'a>,
17 pub unit_for: UnitFor,
20 pub extern_crate_name: InternedString,
22 pub public: bool,
24 pub noprelude: bool,
26}
27
28const VERSION: u32 = 1;
29
30#[derive(serde::Serialize)]
31struct SerializedUnitGraph<'a> {
32 version: u32,
33 units: Vec<SerializedUnit<'a>>,
34 roots: Vec<usize>,
35}
36
37#[derive(serde::Serialize)]
38struct SerializedUnit<'a> {
39 pkg_id: PackageId,
40 target: &'a Target,
41 profile: &'a Profile,
42 platform: CompileKind,
43 mode: CompileMode,
44 features: &'a Vec<InternedString>,
45 #[serde(skip_serializing_if = "std::ops::Not::not")] is_std: bool,
47 dependencies: Vec<SerializedUnitDep>,
48}
49
50#[derive(serde::Serialize)]
51struct SerializedUnitDep {
52 index: usize,
53 extern_crate_name: InternedString,
54 #[serde(skip_serializing_if = "Option::is_none")]
56 public: Option<bool>,
57 #[serde(skip_serializing_if = "Option::is_none")]
59 noprelude: Option<bool>,
60 }
63
64pub fn emit_serialized_unit_graph(
65 root_units: &[Unit<'_>],
66 unit_graph: &UnitGraph<'_>,
67) -> CargoResult<()> {
68 let is_nightly = nightly_features_allowed();
69 let mut units: Vec<(&Unit<'_>, &Vec<UnitDep<'_>>)> = unit_graph.iter().collect();
70 units.sort_unstable();
71 let indices: HashMap<&Unit<'_>, usize> = units
73 .iter()
74 .enumerate()
75 .map(|(i, val)| (val.0, i))
76 .collect();
77 let roots = root_units.iter().map(|root| indices[root]).collect();
78 let ser_units = units
79 .iter()
80 .map(|(unit, unit_deps)| {
81 let dependencies = unit_deps
82 .iter()
83 .map(|unit_dep| {
84 let (public, noprelude) = if is_nightly {
86 (Some(unit_dep.public), Some(unit_dep.noprelude))
87 } else {
88 (None, None)
89 };
90 SerializedUnitDep {
91 index: indices[&unit_dep.unit],
92 extern_crate_name: unit_dep.extern_crate_name,
93 public,
94 noprelude,
95 }
96 })
97 .collect();
98 SerializedUnit {
99 pkg_id: unit.pkg.package_id(),
100 target: unit.target,
101 profile: &unit.profile,
102 platform: unit.kind,
103 mode: unit.mode,
104 features: &unit.features,
105 is_std: unit.is_std,
106 dependencies,
107 }
108 })
109 .collect();
110 let s = SerializedUnitGraph {
111 version: VERSION,
112 units: ser_units,
113 roots,
114 };
115
116 let stdout = std::io::stdout();
117 let mut lock = stdout.lock();
118 serde_json::to_writer(&mut lock, &s)?;
119 write!(lock, "\n")?;
120 Ok(())
121}