Skip to main content

depguard_types/
baseline.rs

1use crate::{Location, ToolMeta};
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use time::OffsetDateTime;
5
6/// Stable schema identifier for depguard baseline files.
7pub const SCHEMA_BASELINE_V1: &str = "depguard.baseline.v1";
8
9/// A baseline entry for a single known finding.
10#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
11pub struct BaselineFinding {
12    /// Stable finding fingerprint.
13    pub fingerprint: String,
14    pub check_id: String,
15    pub code: String,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub location: Option<Location>,
18}
19
20/// Baseline file used to suppress known findings during gradual rollout.
21#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
22pub struct DepguardBaselineV1 {
23    /// Versioned schema identifier for the baseline shape.
24    pub schema: String,
25    pub tool: ToolMeta,
26    #[schemars(with = "String")]
27    #[serde(with = "time::serde::rfc3339")]
28    pub generated_at: OffsetDateTime,
29    /// Fingerprints to suppress. Must be deterministic and unique.
30    #[serde(default)]
31    pub fingerprints: Vec<String>,
32    /// Optional human-readable entries for review and auditing.
33    #[serde(default, skip_serializing_if = "Vec::is_empty")]
34    pub findings: Vec<BaselineFinding>,
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    #[test]
42    fn baseline_roundtrip() {
43        let baseline = DepguardBaselineV1 {
44            schema: SCHEMA_BASELINE_V1.to_string(),
45            tool: ToolMeta {
46                name: "depguard".to_string(),
47                version: "0.1.0".to_string(),
48            },
49            generated_at: OffsetDateTime::UNIX_EPOCH,
50            fingerprints: vec!["abc".to_string()],
51            findings: vec![BaselineFinding {
52                fingerprint: "abc".to_string(),
53                check_id: "deps.no_wildcards".to_string(),
54                code: "wildcard_version".to_string(),
55                location: None,
56            }],
57        };
58
59        let encoded = serde_json::to_string(&baseline).expect("serialize baseline");
60        let decoded: DepguardBaselineV1 =
61            serde_json::from_str(&encoded).expect("deserialize baseline");
62        assert_eq!(decoded, baseline);
63    }
64}