Skip to main content

zcash_address/kind/unified/
revision.rs

1use core::fmt;
2
3/// The revision of ZIP 316 Unified Encoding used for a particular address or viewing key.
4///
5/// Revision 1 has no variant here because it was withdrawn before anything encoded it. It
6/// proposed transparent-permitting Unified Addresses that inspection could not tell apart
7/// from shielded-only ones, and Revision 2 supersedes it with the `zu` and `tu` prefixes,
8/// which make that distinction visible.
9///
10/// See [ZIP 316](https://zips.z.cash/zip-0316) for details.
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
12pub enum Revision {
13    /// Revision 0 of the unified encoding format.
14    ///
15    /// This is the original format, which requires at least one shielded receiver
16    /// in both Unified Addresses and Unified Viewing Keys.
17    R0,
18    /// Revision 2 of the unified encoding format.
19    ///
20    /// This revision adds metadata items, such as address expiry, and drops the
21    /// requirement that a Unified Viewing Key contain a shielded item. A Unified Address
22    /// carries the `zu` prefix when it has no transparent receiver, and the `tu` prefix
23    /// when it has one.
24    R2,
25}
26
27impl Revision {
28    /// Returns the revision number as a `u32`.
29    pub fn number(&self) -> u32 {
30        match self {
31            Revision::R0 => 0,
32            Revision::R2 => 2,
33        }
34    }
35}
36
37impl fmt::Display for Revision {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        match self {
40            Revision::R0 => write!(f, "R0"),
41            Revision::R2 => write!(f, "R2"),
42        }
43    }
44}
45
46impl PartialOrd for Revision {
47    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
48        Some(self.cmp(other))
49    }
50}
51
52impl Ord for Revision {
53    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
54        self.number().cmp(&other.number())
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::Revision;
61    use alloc::string::ToString;
62
63    #[test]
64    fn display() {
65        assert_eq!(Revision::R0.to_string(), "R0");
66        assert_eq!(Revision::R2.to_string(), "R2");
67    }
68
69    #[test]
70    fn ordering() {
71        assert!(Revision::R0 < Revision::R2);
72        assert!(Revision::R2 > Revision::R0);
73        assert_eq!(Revision::R0, Revision::R0);
74    }
75
76    #[test]
77    fn number() {
78        assert_eq!(Revision::R0.number(), 0);
79        assert_eq!(Revision::R2.number(), 2);
80    }
81}