1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#![doc(html_root_url = "https://docs.rs/bc-ur/0.4.1")]
#![warn(rust_2018_idioms)]

//! # Blockchain Commons Uniform Resources ("UR") for Rust
//!
//! [Uniform Resources
//! (URs)](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md)
//! are URI-encoded [CBOR](https://cbor.io) structures developed by [Blockchain
//! Commons](https://blockchaincommons.com). This crate is an opinionated
//! wrapper around the [ur](https://crates.io/crates/ur) crate by [Dominik
//! Spicher](https://github.com/dspicher), and is intended primarily for use in
//! higher-level Blockchain Commmons projects like [Gordian
//! Envelope](https://crates.io/crates/bc-envelope).
//!
//! It is a requirement of the UR specification that the CBOR encoded as URs
//! conform to Gordian dCBOR, which is a deterministic profile of CBOR currently
//! specified in [this IETF Internet
//! Draft](https://datatracker.ietf.org/doc/draft-mcnally-deterministic-cbor/).
//! The dependency `dcbor` crate can be used directly for that purpose. This
//! crate provides the traits `UREncodable`, `URDecodable`, and `URCodable` that
//! are built on traits from the `dcbor` crate such as `CBORTaggedEncodable` and
//! `CBORTaggedDecodable`. It is strongly recommended that adopters of URs
//! implement these traits for their types.
//!
//! This crate does not currenly provide opinionated affordances for multi-part
//! URs using fountain codes, but the dependency `ur` crate can be used directly
//! for that purpose.
//!
//! # Getting Started
//!
//! Add the following to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! bc-ur = "0.4.1"
//! ```
//!
//! # Specification
//!
//! The primary specification for URs is [BCR-2020-005:
//! Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md)
//! and the Swift implementation [URKit](https://github.com/BlockchainCommons/URKit).
//!
//! # Usage
//!
//! Encode a CBOR structure as a UR.
//!
//! ```
//! # fn main() {
//! # {
//! use dcbor::prelude::*;
//! use bc_ur::prelude::*;
//! let cbor: CBOR = vec![1, 2, 3].into();
//! let ur = UR::new("test", cbor).unwrap();
//! let ur_string = ur.string();
//! assert_eq!(ur_string, "ur:test/lsadaoaxjygonesw");
//! # }
//! # }
//! ```
//!
//! Decode a UR back to a CBOR structure.
//!
//! ```
//! # fn main() {
//! # {
//! use dcbor::prelude::*;
//! use bc_ur::prelude::*;
//! let ur_string = "ur:test/lsadaoaxjygonesw";
//! let ur = UR::from_ur_string(ur_string).unwrap();
//! assert_eq!(ur.ur_type_str(), "test");
//! let ur_cbor = ur.cbor();
//! let array_cbor: CBOR = vec![1, 2, 3].into();
//! assert_eq!(ur_cbor, array_cbor);
//! # }
//! # }
//! ```

mod ur;
pub use ur::UR;
pub mod bytewords;

mod ur_type;
pub use ur_type::URType;

mod error;
pub use error::URError as Error;

mod utils;

mod ur_encodable;
pub use ur_encodable::UREncodable;

mod ur_decodable;
pub use ur_decodable::URDecodable;

mod ur_codable;
pub use ur_codable::URCodable;

pub mod prelude;

#[cfg(test)]
mod tests {
    #[test]
    fn test_readme_deps() {
        version_sync::assert_markdown_deps_updated!("README.md");
    }

    #[test]
    fn test_html_root_url() {
        version_sync::assert_html_root_url_updated!("src/lib.rs");
    }
}

#[cfg(test)]
mod example_tests {
    use dcbor::prelude::*;
    use crate::*;

    #[test]
    fn encode() {
        let cbor: CBOR = vec![1, 2, 3].into();
        let ur = UR::new("test", cbor).unwrap();
        let ur_string = ur.string();
        assert_eq!(ur_string, "ur:test/lsadaoaxjygonesw");
    }

    #[test]
    fn decode() {
        let ur_string = "ur:test/lsadaoaxjygonesw";
        let ur = UR::from_ur_string(ur_string).unwrap();
        assert_eq!(ur.ur_type_str(), "test");
        assert_eq!(<UR as Into<CBOR>>::into(ur), <Vec<i32> as Into<CBOR>>::into(vec![1, 2, 3]));
    }
}