Skip to main content

canic_core/ids/
release_set.rs

1//! Module: ids::release_set
2//!
3//! Responsibility: identify one exact canonical Fleet Subnet Root release-set manifest.
4//! Does not own: manifest encoding, artifact storage, publication, or active-set policy.
5//! Boundary: the host derives this digest from validated canonical manifest bytes.
6
7use std::fmt::{self, Display};
8
9use candid::CandidType;
10use serde::{Deserialize, Serialize};
11
12///
13/// ReleaseSetDigest
14///
15/// SHA-256 identity of one canonical Fleet Subnet Root release-set manifest.
16///
17
18#[derive(
19    CandidType, Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize,
20)]
21#[serde(transparent)]
22pub struct ReleaseSetDigest([u8; 32]);
23
24impl ReleaseSetDigest {
25    #[must_use]
26    pub const fn from_bytes(bytes: [u8; 32]) -> Self {
27        Self(bytes)
28    }
29
30    #[must_use]
31    pub const fn as_bytes(&self) -> &[u8; 32] {
32        &self.0
33    }
34
35    #[must_use]
36    pub const fn into_bytes(self) -> [u8; 32] {
37        self.0
38    }
39}
40
41impl Display for ReleaseSetDigest {
42    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
43        for byte in self.0 {
44            write!(formatter, "{byte:02x}")?;
45        }
46        Ok(())
47    }
48}
49
50// -----------------------------------------------------------------------------
51// Tests
52// -----------------------------------------------------------------------------
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn digest_has_exact_bytes_text_and_candid_representation() {
60        let digest = ReleaseSetDigest::from_bytes([0xab; 32]);
61
62        assert_eq!(digest.as_bytes(), &[0xab; 32]);
63        assert_eq!(digest.into_bytes(), [0xab; 32]);
64        assert_eq!(digest.to_string(), "ab".repeat(32));
65
66        let bytes = candid::encode_one(digest).expect("encode Release Set digest");
67        assert_eq!(
68            candid::decode_one::<ReleaseSetDigest>(&bytes).expect("decode Release Set digest"),
69            digest
70        );
71    }
72}