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}