kodumaro_uuid_cli/
lib.rs

1//! UUID generator ([RFC 4122](https://www.rfc-editor.org/rfc/rfc4122)).
2//!
3//! This is a command line tool, **do not** install it using `cargo add`!!
4//!
5//! # Installation guide
6//!
7//! You need to enable `uuid_unstable` configuration flag:
8//!
9//! ```sh
10//! RUSTFLAGS='--cfg uuid_unstable' cargo install kodumaro-uuid-cli
11//! ```
12//!
13//! It’s gonna create a `~/.cargo/bin/uuid` executable.
14//!
15//! # Usage
16//!
17//! ```sh
18//! Usage: uuid [COMMAND]
19//!
20//! Commands:
21//!   nil   generates nil UUID
22//!   v1    generates UUIDv1, time-based UUID
23//!   v3    generates UUIDv3, name-based MD5 UUID
24//!   v4    generates UUIDv4, random UUID
25//!   v5    generates UUIDv5, name-based SHA1 UUID
26//!   v6    generates UUIDv6, field-compatible version of UUIDv1
27//!   v7    generates UUIDv7, Unix Epoch timestamp-based UUID
28//!   v8    generates UUIDv8, vendor-specific UUID
29//!   help  Print this message or the help of the given subcommand(s)
30//!
31//! Options:
32//!   -h, --help  Print help
33//! ```
34//!
35//! ## Examples
36//!
37//! ```sh
38//! $ uuid
39//! urn:uuid:4db78d44-e170-42a3-bf93-418b9baeae2b
40//!
41//! $ uuid help
42//! UUID generator (RFC 4122), see <https://www.rfc-editor.org/rfc/rfc4122>
43//!
44//! It generates UUID versions 1, 3, 4, 5, 6, 7 and 8, and nil UUID.
45//!
46//! It returns the URN; if you want to emulate the same behaviour as uuigen (plain
47//! UUID), set the env-var:
48//!
49//! export UUID_MODE=uuidgen
50//!
51//!
52//! Usage: uuid [COMMAND]
53//!
54//! Commands:
55//!   nil
56//!           generates nil UUID
57//!   v1
58//!           generates UUIDv1, time-based UUID
59//!   v3
60//!           generates UUIDv3, name-based MD5 UUID
61//!   v4
62//!           generates UUIDv4, random UUID
63//!   v5
64//!           generates UUIDv5, name-based SHA1 UUID
65//!   v6
66//!           generates UUIDv6, field-compatible version of UUIDv1
67//!   v7
68//!           generates UUIDv7, Unix Epoch timestamp-based UUID
69//!   v8
70//!           generates UUIDv8, vendor-specific UUID
71//!   help
72//!           Print this message or the help of the given subcommand(s)
73//!
74//! Options:
75//!   -h, --help
76//!           Print help (see a summary with '-h')
77//!
78//! $ uuid nil
79//! urn:uuid:00000000-0000-0000-0000-000000000000
80//!
81//! $ uuid v1
82//! urn:uuid:xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx
83//!
84//! $ uuid v3 $(uuid v7) test
85//! urn:uuid:5604097f-ffa0-3934-9635-cb03308240fe
86//!
87//! $ uuid v5 $(uuid v7) test
88//! urn:uuid:d8beedbe-ca82-57ef-8dc1-ca501caeb151
89//!
90//! $ uuid v6 blabla
91//! urn:uuid:xxxxxxxx-xxxx-6xxx-xxxx-xxxxxxxxxxxx
92//!
93//! $ uuid v7
94//! urn:uuid:018800be-993e-7990-b64a-900ba7dd54e3
95//!
96//! $ uuid v8 'Some long data!'
97//! urn:uuid:536f6d65-206c-8f6e-a720-646174612100
98//!
99//! $ UUID_MODE=uuidgen uuid v7
100//! 01880c8f-d233-7be3-b1f5-95ea2650457f
101//!
102//! $ uuid help v8
103//! generates UUIDv8, vendor-specific UUID
104//!
105//! Usage: uuid v8 <METADATA>
106//!
107//! Arguments:
108//!   <METADATA>  vendor’s metadata to be encoded into the UUIDv8, up to 16 bytes
109//!
110//! Options:
111//!   -h, --help  Print help
112//! ```
113//!
114//! # License
115//!
116//! - [The 3-Clause BSD License](https://opensource.org/license/bsd-3-clause/)
117
118extern crate uuid;
119mod errors;
120
121use eyre::Result;
122pub use errors::UUIDError;
123use mac_address::get_mac_address;
124use uuid::Uuid;
125
126
127pub fn get_v1() -> Result<String> {
128    let addr = get_mac_address()?.ok_or_else(|| UUIDError::Missing("mac address".to_owned()))?;
129    Ok(format!("{}", Uuid::now_v1(&addr.bytes())))
130}
131
132pub fn get_v3(namespace: Uuid, name: String) -> Result<String> {
133    Ok(format!("{}", Uuid::new_v3(&namespace, name.as_bytes())))
134}
135
136pub fn get_v4() -> Result<String> {
137    Ok(format!("{}", Uuid::new_v4()))
138}
139
140pub fn get_v5(namespace: Uuid, name: String) -> Result<String> {
141    Ok(format!("{}", Uuid::new_v5(&namespace, name.as_bytes())))
142}
143
144pub fn get_v6(node_id: String) -> Result<String> {
145    if node_id.len() < 6 {
146        return Err(UUIDError::WrongLength {
147            expected: 6,
148            got: node_id.len(),
149        }
150        .into());
151    }
152    let node_id: &[u8; 6] = &node_id.as_bytes()[0..6].try_into()?;
153    Ok(format!("{}", Uuid::now_v6(node_id)))
154}
155
156pub fn get_v7() -> Result<String> {
157    Ok(format!("{}", Uuid::now_v7()))
158}
159
160pub fn get_v8(metadata: String) -> Result<String> {
161    let metadata = metadata.as_bytes();
162    let mut buf = [0_u8; 16];
163    let length = metadata.len();
164    let length = if length > 16 { 16 } else { length };
165    buf[..length].copy_from_slice(&metadata[..length]);
166    Ok(format!("{}", Uuid::new_v8(buf)))
167}