#![expect(
clippy::print_stderr,
reason = "stub sidecar emits diagnostic lines on stderr for failure modes; tests assert against them"
)]
use std::io::{Read, Write};
use std::process::ExitCode;
use fallow_cov_protocol::{
CaptureQuality, PROTOCOL_VERSION, ReportVerdict, Request, Response, Summary,
};
fn main() -> ExitCode {
let mut buf = Vec::new();
let _ = std::io::stdin().read_to_end(&mut buf);
let _parsed: Option<Request> = serde_json::from_slice(&buf).ok();
let mode = std::env::var("FALLOW_STUB_MODE").unwrap_or_default();
match mode.as_str() {
"" | "ok" => emit_clean_response(PROTOCOL_VERSION, None),
"protocol-mismatch" => emit_clean_response("99.0.0", None),
"capture-quality-short" => emit_clean_response(
PROTOCOL_VERSION,
Some(CaptureQuality {
window_seconds: 720,
instances_observed: 1,
lazy_parse_warning: true,
untracked_ratio_percent: 42.5,
}),
),
"capture-quality-long" => emit_clean_response(
PROTOCOL_VERSION,
Some(CaptureQuality {
window_seconds: 7 * 24 * 3600,
instances_observed: 4,
lazy_parse_warning: false,
untracked_ratio_percent: 3.1,
}),
),
"malformed-stdout" => emit_bytes(b"definitely not JSON\n"),
"empty-stdout" => ExitCode::SUCCESS,
"exit-4" => {
eprintln!("stub sidecar: simulated protocol mismatch");
ExitCode::from(4)
}
"exit-5" => {
eprintln!("stub sidecar: simulated input parse error");
ExitCode::from(5)
}
"exit-6" => {
eprintln!("stub sidecar: simulated internal error");
ExitCode::from(6)
}
other => {
eprintln!("stub sidecar: unknown FALLOW_STUB_MODE={other}");
ExitCode::from(2)
}
}
}
fn emit_clean_response(
protocol_version: &str,
capture_quality: Option<CaptureQuality>,
) -> ExitCode {
let response = Response {
protocol_version: protocol_version.to_owned(),
verdict: ReportVerdict::Clean,
summary: Summary {
functions_tracked: 0,
functions_hit: 0,
functions_unhit: 0,
functions_untracked: 0,
coverage_percent: 0.0,
trace_count: 0,
period_days: 0,
deployments_seen: 0,
capture_quality,
},
findings: Vec::new(),
hot_paths: Vec::new(),
watermark: None,
errors: Vec::new(),
warnings: Vec::new(),
};
match serde_json::to_vec(&response) {
Ok(bytes) => emit_bytes(&bytes),
Err(err) => {
eprintln!("stub sidecar: failed to serialize response: {err}");
ExitCode::from(6)
}
}
}
fn emit_bytes(bytes: &[u8]) -> ExitCode {
let mut stdout = std::io::stdout().lock();
if stdout.write_all(bytes).is_err() || stdout.flush().is_err() {
return ExitCode::from(6);
}
ExitCode::SUCCESS
}