Skip to main content

dry4rust/suppression/
baseline_entry.rs

1// Copyright (c) 2026 Matjaz Domen Pecan
2// Copyright 2026 Umberto Gotti <umberto.gotti@umbertogotti.dev>
3// Licensed under the MIT License
4// SPDX-License-Identifier: MIT
5
6use serde::{Deserialize, Serialize};
7
8use crate::grouper::DuplicateGroup;
9use crate::suppression::baseline_kind::BaselineKind;
10
11/// One duplicate group as the baseline recorded it.
12///
13/// `members` is part of the identity, not decoration. An exact group is keyed
14/// by the fingerprint its members share, so a third copy of an already-recorded
15/// function does not change the fingerprint. Without the count, adding that
16/// copy would be inherited duplication; with it, the group has grown past what
17/// was recorded and is reported.
18///
19/// `names` is decoration, and deliberately so: a baseline nobody can read is a
20/// baseline nobody audits. Nothing matches on it.
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
22pub struct BaselineEntry {
23    /// Which set of groups this was recorded from.
24    pub kind: BaselineKind,
25    /// The group's fingerprint, as hex.
26    pub fingerprint: String,
27    /// How many members the group had when it was recorded.
28    pub members: usize,
29    /// What those members were called, for a reader.
30    #[serde(default, skip_serializing_if = "Vec::is_empty")]
31    pub names: Vec<String>,
32}
33
34impl BaselineEntry {
35    /// Record `group` as inherited duplication of `kind`.
36    #[must_use]
37    pub fn of(kind: BaselineKind, group: &DuplicateGroup) -> Self {
38        Self {
39            kind,
40            fingerprint: group.fingerprint.to_hex(),
41            members: group.members.len(),
42            names: group.members.iter().map(|m| m.name.clone()).collect(),
43        }
44    }
45
46    /// Whether this entry accounts for `group` in full.
47    ///
48    /// A group that has grown since it was recorded is not accounted for, so
49    /// the new copy is reported rather than inherited.
50    #[must_use]
51    pub fn admits(&self, kind: BaselineKind, group: &DuplicateGroup) -> bool {
52        self.kind == kind
53            && self.fingerprint == group.fingerprint.to_hex()
54            && group.members.len() <= self.members
55    }
56}