use std::collections::HashMap;
use std::io::{BufRead, BufReader};
use std::process::{Command, Stdio};
use cargo_metadata::PackageId;
use serde::{Deserialize, Serialize};
const CARGO_CUSTOM_PROFILE: [&str; 2] = ["--config", r#"profile.depwiz.inherits="dev""#];
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
enum Reason {
TimingInfo,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Mode {
Build,
RunCustomBuild,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Message {
reason: Reason,
pub package_id: PackageId,
pub target: super::Target,
pub mode: Mode,
pub duration: f64,
pub rmeta_time: Option<f64>,
}
#[derive(Clone, Debug)]
pub struct Output {
pub repr: HashMap<PackageId, Vec<Message>>,
}
impl Output {
pub fn generate() -> Vec<u8> {
Command::new("cargo")
.arg("clean")
.args(CARGO_CUSTOM_PROFILE)
.args(&["--profile", "depwiz"])
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.output()
.unwrap();
let timings_output = Command::new("cargo")
.arg("build")
.args(CARGO_CUSTOM_PROFILE)
.args(&[
"--profile",
"depwiz",
"-Zunstable-options",
"--timings=json",
])
.stderr(Stdio::inherit())
.output()
.unwrap();
timings_output.stdout
}
pub fn new(source_data: &[u8]) -> Self {
let mut timings = HashMap::new();
let mut timings_buffer = BufReader::new(source_data);
let mut message_buffer = Vec::new();
loop {
timings_buffer
.read_until(b'\n', &mut message_buffer)
.unwrap();
let json_message: Message = match serde_json::from_slice(&message_buffer) {
Ok(message) => message,
Err(err) => {
use serde_json::error::Category;
match err.classify() {
Category::Eof => break,
Category::Data => todo!(
"JSON object not properly handled, got `{err:?}` for message: `{}`",
String::from_utf8(message_buffer.clone()).unwrap()
),
_ => {
panic!("Unexpected error while parsing: {err:?}");
}
}
}
};
let pkg_timings: &mut Vec<Message> =
timings.entry(json_message.package_id.clone()).or_default();
pkg_timings.push(json_message);
message_buffer.clear();
}
Self { repr: timings }
}
}