bc_ur/
ur_codable.rs

1use crate::{UREncodable, URDecodable};
2
3/// A type that can be encoded to and decoded from a UR.
4pub trait URCodable {}
5
6impl<T> URCodable for T where T: UREncodable + URDecodable { }
7
8#[cfg(test)]
9mod tests {
10    use dcbor::{CBOR, Tag, CBORTaggedEncodable, CBORTaggedDecodable, CBORTagged};
11    use anyhow::{Error, Result};
12
13    use super::*;
14
15    #[derive(Debug, PartialEq)]
16    struct Test {
17        s: String,
18    }
19
20    impl Test {
21        fn new(s: &str) -> Self {
22            Self { s: s.to_string() }
23        }
24    }
25
26    impl CBORTagged for Test {
27        fn cbor_tags() -> Vec<Tag> {
28            vec![Tag::new(24, "leaf")]
29        }
30    }
31
32    impl From<Test> for CBOR {
33        // This ensures that asking for the CBOR for this type will always
34        // return a tagged CBOR value.
35        fn from(value: Test) -> Self {
36            value.tagged_cbor()
37        }
38    }
39
40    impl CBORTaggedEncodable for Test {
41        // This is the core of the CBOR encoding for this type. It is the
42        // untagged CBOR encoding.
43        fn untagged_cbor(&self) -> CBOR {
44            self.s.clone().into()
45        }
46    }
47
48    impl TryFrom<CBOR> for Test {
49        type Error = Error;
50
51        // This ensures that asking for the CBOR for this type will always
52        // expect a tagged CBOR value.
53        fn try_from(cbor: CBOR) -> Result<Self> {
54            Self::from_tagged_cbor(cbor)
55        }
56    }
57
58    impl CBORTaggedDecodable for Test {
59        // This is the core of the CBOR decoding for this type. It is the
60        // untagged CBOR decoding.
61        fn from_untagged_cbor(cbor: CBOR) -> Result<Self> {
62            let s: String = cbor.try_into()?;
63            Ok(Self::new(&s))
64        }
65    }
66
67    #[test]
68    fn test_ur_codable() {
69        let test = Test::new("test");
70        let ur = test.ur();
71        let ur_string = ur.string();
72        assert_eq!(ur_string, "ur:leaf/iejyihjkjygupyltla");
73        let test2 = Test::from_ur_string(ur_string).unwrap();
74        assert_eq!(test.s, test2.s);
75    }
76}