Skip to main content

made_core/value_objects/ceremony/
definition_pin.rs

1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5use super::{CeremonyDefinitionDigest, CeremonyName, CeremonyVersion};
6
7/// An immutable reference to one published ceremony definition.
8///
9/// Name and version say which definition; the digest says which bytes.
10/// A composition that pinned only the version would follow a republish
11/// it never agreed to, so the digest is part of the reference rather
12/// than a check performed beside it.
13#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
14pub struct DefinitionPin {
15    name: CeremonyName,
16    version: CeremonyVersion,
17    digest: CeremonyDefinitionDigest,
18}
19
20impl DefinitionPin {
21    #[must_use]
22    pub const fn new(
23        name: CeremonyName,
24        version: CeremonyVersion,
25        digest: CeremonyDefinitionDigest,
26    ) -> Self {
27        Self {
28            name,
29            version,
30            digest,
31        }
32    }
33
34    #[must_use]
35    pub const fn name(&self) -> &CeremonyName {
36        &self.name
37    }
38
39    #[must_use]
40    pub const fn version(&self) -> &CeremonyVersion {
41        &self.version
42    }
43
44    #[must_use]
45    pub const fn digest(&self) -> CeremonyDefinitionDigest {
46        self.digest
47    }
48
49    /// Whether this pin names the same bytes as another.
50    #[must_use]
51    pub fn matches(&self, other: &Self) -> bool {
52        self == other
53    }
54}
55
56impl fmt::Display for DefinitionPin {
57    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
58        write!(formatter, "{}@{}", self.name, self.version)
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    fn pin(version: &str, fill: u8) -> DefinitionPin {
67        DefinitionPin::new(
68            CeremonyName::new("review").unwrap(),
69            CeremonyVersion::new(version).unwrap(),
70            CeremonyDefinitionDigest::from_bytes([fill; 32]),
71        )
72    }
73
74    #[test]
75    fn a_republished_version_is_not_the_pin_that_was_agreed_to() {
76        assert!(pin("1.0.0", 0x0a).matches(&pin("1.0.0", 0x0a)));
77        assert!(!pin("1.0.0", 0x0a).matches(&pin("1.0.0", 0x0b)));
78        assert_eq!(pin("1.0.0", 0x0a).to_string(), "review@1.0.0");
79    }
80}