cargo/util/
machine_message.rs

1use std::path::{Path, PathBuf};
2
3use cargo_util_schemas::core::PackageIdSpec;
4use serde::Serialize;
5use serde::ser;
6use serde_json::value::RawValue;
7
8use crate::core::Target;
9use crate::core::compiler::{CompilationSection, CompileMode};
10
11pub trait Message: ser::Serialize {
12    fn reason(&self) -> &str;
13
14    fn to_json_string(&self) -> String {
15        #[derive(Serialize)]
16        struct WithReason<'a, S: Serialize> {
17            reason: &'a str,
18            #[serde(flatten)]
19            msg: &'a S,
20        }
21        let with_reason = WithReason {
22            reason: self.reason(),
23            msg: &self,
24        };
25        serde_json::to_string(&with_reason).unwrap()
26    }
27}
28
29#[derive(Serialize)]
30pub struct FromCompiler<'a> {
31    pub package_id: PackageIdSpec,
32    pub manifest_path: &'a Path,
33    pub target: &'a Target,
34    pub message: Box<RawValue>,
35}
36
37impl<'a> Message for FromCompiler<'a> {
38    fn reason(&self) -> &str {
39        "compiler-message"
40    }
41}
42
43#[derive(Serialize)]
44pub struct Artifact<'a> {
45    pub package_id: PackageIdSpec,
46    pub manifest_path: PathBuf,
47    pub target: &'a Target,
48    pub profile: ArtifactProfile,
49    pub features: Vec<String>,
50    pub filenames: Vec<PathBuf>,
51    pub executable: Option<PathBuf>,
52    pub fresh: bool,
53}
54
55impl<'a> Message for Artifact<'a> {
56    fn reason(&self) -> &str {
57        "compiler-artifact"
58    }
59}
60
61/// This is different from the regular `Profile` to maintain backwards
62/// compatibility (in particular, `test` is no longer in `Profile`, but we
63/// still want it to be included here).
64#[derive(Serialize)]
65pub struct ArtifactProfile {
66    pub opt_level: &'static str,
67    pub debuginfo: Option<ArtifactDebuginfo>,
68    pub debug_assertions: bool,
69    pub overflow_checks: bool,
70    pub test: bool,
71}
72
73/// Internally this is an enum with different variants, but keep using 0/1/2 as integers for compatibility.
74#[derive(Serialize)]
75#[serde(untagged)]
76pub enum ArtifactDebuginfo {
77    Int(u32),
78    Named(&'static str),
79}
80
81#[derive(Serialize)]
82pub struct BuildScript<'a> {
83    pub package_id: PackageIdSpec,
84    pub linked_libs: &'a [String],
85    pub linked_paths: &'a [String],
86    pub cfgs: &'a [String],
87    pub env: &'a [(String, String)],
88    pub out_dir: &'a Path,
89}
90
91impl<'a> Message for BuildScript<'a> {
92    fn reason(&self) -> &str {
93        "build-script-executed"
94    }
95}
96
97#[derive(Serialize)]
98pub struct TimingInfo<'a> {
99    pub package_id: PackageIdSpec,
100    pub target: &'a Target,
101    pub mode: CompileMode,
102    pub duration: f64,
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub rmeta_time: Option<f64>,
105    #[serde(skip_serializing_if = "Vec::is_empty")]
106    pub sections: Vec<(String, CompilationSection)>,
107}
108
109impl<'a> Message for TimingInfo<'a> {
110    fn reason(&self) -> &str {
111        "timing-info"
112    }
113}
114
115#[derive(Serialize)]
116pub struct BuildFinished {
117    pub success: bool,
118}
119
120impl Message for BuildFinished {
121    fn reason(&self) -> &str {
122        "build-finished"
123    }
124}