pub mod fingerprint;
mod status;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CrateId(String);
impl CrateId {
pub fn name(&self) -> &str {
self.0.split_whitespace().next().unwrap_or(&self.0)
}
#[cfg(test)]
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
}
impl std::fmt::Display for CrateId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WorkKind {
Compiling,
Checking,
Building,
}
impl WorkKind {
pub fn verb(self) -> &'static str {
match self {
Self::Compiling => "Compiling",
Self::Checking => "Checking",
Self::Building => "Building",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StatusKind {
Fresh,
Dirty { reason: String },
Work(WorkKind),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CrateStatus {
pub id: CrateId,
pub kind: StatusKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StderrLine {
Status(CrateStatus),
FingerprintTrace(String),
Other(String),
}
pub fn classify(line: &str) -> StderrLine {
let trimmed = line.trim_start();
if let Some(status) = status::parse(trimmed) {
return StderrLine::Status(status);
}
if fingerprint::is_fingerprint_trace_line(trimmed) {
return StderrLine::FingerprintTrace(trimmed.to_owned());
}
StderrLine::Other(line.to_owned())
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn classifies_indented_status_lines() {
assert_eq!(
classify(" Fresh foo v0.1.0 (/tmp/foo)"),
StderrLine::Status(CrateStatus {
id: CrateId::new("foo v0.1.0"),
kind: StatusKind::Fresh,
})
);
}
#[test]
fn keeps_indentation_on_unrecognised_lines() {
assert_eq!(
classify(" warning: something happened"),
StderrLine::Other(" warning: something happened".to_string())
);
}
#[test]
fn trims_indentation_from_fingerprint_trace_lines() {
assert_eq!(
classify(" TRACE cargo::core::compiler::fingerprint: err: changed"),
StderrLine::FingerprintTrace(
"TRACE cargo::core::compiler::fingerprint: err: changed".to_string()
)
);
}
#[test]
fn classifies_run_and_finish_lines_as_other() {
assert!(matches!(
classify(" Running `rustc --crate-name foo`"),
StderrLine::Other(_)
));
assert!(matches!(
classify(" Finished `dev` profile [unoptimized] target(s) in 0.10s"),
StderrLine::Other(_)
));
}
}