1use super::{Diagnostic, PackageId, Target};
2use camino::Utf8PathBuf;
3#[cfg(feature = "builder")]
4use derive_builder::Builder;
5use serde::{Deserialize, Serialize};
6use std::fmt;
7use std::io::{self, BufRead, Lines, Read};
8
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
12#[cfg_attr(feature = "builder", derive(Builder))]
13#[non_exhaustive]
14#[cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))]
15pub struct ArtifactProfile {
16 pub opt_level: String,
18 pub debuginfo: Option<u32>,
20 pub debug_assertions: bool,
23 pub overflow_checks: bool,
25 pub test: bool,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
31#[cfg_attr(feature = "builder", derive(Builder))]
32#[non_exhaustive]
33#[cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))]
34pub struct Artifact {
35 pub package_id: PackageId,
37 pub target: Target,
39 pub profile: ArtifactProfile,
41 pub features: Vec<String>,
43 pub filenames: Vec<Utf8PathBuf>,
46 pub executable: Option<Utf8PathBuf>,
48 pub fresh: bool,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
55#[cfg_attr(feature = "builder", derive(Builder))]
56#[non_exhaustive]
57#[cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))]
58pub struct CompilerMessage {
59 pub package_id: PackageId,
61 pub target: Target,
63 pub message: Diagnostic,
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
69#[cfg_attr(feature = "builder", derive(Builder))]
70#[non_exhaustive]
71#[cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))]
72pub struct BuildScript {
73 pub package_id: PackageId,
75 pub linked_libs: Vec<Utf8PathBuf>,
77 pub linked_paths: Vec<Utf8PathBuf>,
79 pub cfgs: Vec<String>,
81 pub env: Vec<(String, String)>,
83 #[serde(default)]
87 pub out_dir: Utf8PathBuf,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
92#[cfg_attr(feature = "builder", derive(Builder))]
93#[non_exhaustive]
94#[cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))]
95pub struct BuildFinished {
96 pub success: bool,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
102#[non_exhaustive]
103#[serde(tag = "reason", rename_all = "kebab-case")]
104pub enum Message {
105 CompilerArtifact(Artifact),
107 CompilerMessage(CompilerMessage),
109 BuildScriptExecuted(BuildScript),
111 BuildFinished(BuildFinished),
116 #[serde(skip)]
119 TextLine(String),
120}
121
122impl Message {
123 pub fn parse_stream<R: BufRead>(input: R) -> MessageIter<R> {
126 MessageIter {
127 lines: input.lines(),
128 }
129 }
130}
131
132impl fmt::Display for CompilerMessage {
133 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134 write!(f, "{}", self.message)
135 }
136}
137
138pub struct MessageIter<R> {
140 lines: Lines<R>,
141}
142
143impl<R: BufRead> Iterator for MessageIter<R> {
144 type Item = io::Result<Message>;
145 fn next(&mut self) -> Option<Self::Item> {
146 let line = self.lines.next()?;
147 let message = line.map(|it| {
148 let mut deserializer = serde_json::Deserializer::from_str(&it);
149 deserializer.disable_recursion_limit();
150 Message::deserialize(&mut deserializer).unwrap_or(Message::TextLine(it))
151 });
152 Some(message)
153 }
154}
155
156type MessageIterator<R> =
158 serde_json::StreamDeserializer<'static, serde_json::de::IoRead<R>, Message>;
159
160#[deprecated(note = "Use Message::parse_stream instead")]
163pub fn parse_messages<R: Read>(input: R) -> MessageIterator<R> {
164 serde_json::Deserializer::from_reader(input).into_iter::<Message>()
165}