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}