pub struct TinyId { /* private fields */ }
Expand description
A tiny 8-byte ID type that is NOT cryptographically secure, but is easy and convenient for tasks that don’t require the utmost security or uniqueness. During lightweight testing, between 1 and 10 million IDs can be generated without any collisions, and performance has been pretty good.
Implementations§
Source§impl TinyId
impl TinyId
Sourcepub const LETTER_COUNT: usize = 64usize
pub const LETTER_COUNT: usize = 64usize
The number of letters that make up the potential pool of characters for a TinyId
.
Sourcepub const NULL_DATA: [u8; 8]
pub const NULL_DATA: [u8; 8]
An instance of a fully null byte array, used as the basis for null ids.
Sourcepub const fn is_valid_byte(byte: u8) -> bool
pub const fn is_valid_byte(byte: u8) -> bool
Test whether the given byte is valid for use as one of the 8 bytes in a TinyId
.
This function exists because I’m tired of writing if LETTERS.contains(&byte)
everywhere.
Hopefully it is also more efficient to do it this way.
Letters (as u8):
[45, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
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, 95, 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]
aka
[45, 48..=57, 65..=90, 95, 97..=122]
Sourcepub fn null() -> Self
pub fn null() -> Self
Create an instance of the null
TinyId
.
Examples found in repository?
5fn main() {
6 // Create a random ID
7 let rand_id = TinyId::random();
8
9 // Parse a string into a Result<TinyId, TinyIdError> for possibly unsafe / invalid ID strings
10 let maybe = TinyId::from_str("AAAABBBB");
11 assert!(maybe.is_ok());
12 let bad = TinyId::from_str("AAAABBB");
13 assert!(bad.is_err());
14
15 // Parse a string you **KNOW** is safe into a TinyId
16 let parsed = TinyId::from_str_unchecked("AAAABBBB");
17
18 // All expected operations are available on TinyIds
19 // Equality is a simple byte comparison so it should be fast and cheap!
20 assert_eq!(maybe.unwrap(), parsed);
21
22 // IDs may be printed using Display or Debug
23 println!("Random ID: {rand_id}");
24 println!("Parsed ID: {parsed}");
25 println!(" Debug ID: {parsed:?}");
26
27 // IDs are small!
28 println!("TinyID Size: {}", std::mem::size_of::<TinyId>());
29
30 // IDs are case-sensitive
31 let parsed2 = TinyId::from_str_unchecked("aaaaBBBB");
32 assert_ne!(parsed, parsed2);
33
34 // Check whether an ID starts with a given string. Example use case would be providing a
35 // list of IDs to a user, and asking for a partial string to match against so the user
36 // doesn't have to type the entire thing.
37 assert!(parsed.starts_with("AAAA"));
38 assert!(parsed.ends_with("BBBB"));
39 assert!(!parsed.starts_with("BBBB"));
40
41 // IDs are copied when assigned.
42 let mut switched = parsed;
43 assert_eq!(switched, parsed);
44
45 // Validity can be checked, and a "marker" exists for null / invalid IDs.
46 assert!(switched.is_valid());
47 assert!(!switched.is_null());
48 assert_ne!(switched, TinyId::null());
49 // Mutable IDs can be made null. This change has no effect on the `parsed` variable.
50 switched.make_null();
51 assert!(!switched.is_valid());
52 assert!(switched.is_null());
53 assert_eq!(switched, TinyId::null());
54}
Sourcepub fn random() -> Self
pub fn random() -> Self
Create a new random TinyId
.
Examples found in repository?
More examples
42fn run_until_collision() -> usize {
43 let mut ids = std::collections::HashSet::new();
44 let mut iters = 0;
45 loop {
46 iters += 1;
47 let id = TinyId::random();
48 if !ids.insert(id) {
49 break;
50 }
51 }
52 iters
53}
11fn main() {
12 println!("Generating {ITERS} TinyIds...");
13 for x in (0..(ITERS)).step_by(2) {
14 let id = TinyId::random();
15 let mut n = x + 1;
16 print!("#{n:03}: {id}");
17 print!(" | ");
18 let id = TinyId::random();
19 n += 1;
20 println!("#{n:03}: {id}");
21 }
22}
5fn main() {
6 // Create a random ID
7 let rand_id = TinyId::random();
8
9 // Parse a string into a Result<TinyId, TinyIdError> for possibly unsafe / invalid ID strings
10 let maybe = TinyId::from_str("AAAABBBB");
11 assert!(maybe.is_ok());
12 let bad = TinyId::from_str("AAAABBB");
13 assert!(bad.is_err());
14
15 // Parse a string you **KNOW** is safe into a TinyId
16 let parsed = TinyId::from_str_unchecked("AAAABBBB");
17
18 // All expected operations are available on TinyIds
19 // Equality is a simple byte comparison so it should be fast and cheap!
20 assert_eq!(maybe.unwrap(), parsed);
21
22 // IDs may be printed using Display or Debug
23 println!("Random ID: {rand_id}");
24 println!("Parsed ID: {parsed}");
25 println!(" Debug ID: {parsed:?}");
26
27 // IDs are small!
28 println!("TinyID Size: {}", std::mem::size_of::<TinyId>());
29
30 // IDs are case-sensitive
31 let parsed2 = TinyId::from_str_unchecked("aaaaBBBB");
32 assert_ne!(parsed, parsed2);
33
34 // Check whether an ID starts with a given string. Example use case would be providing a
35 // list of IDs to a user, and asking for a partial string to match against so the user
36 // doesn't have to type the entire thing.
37 assert!(parsed.starts_with("AAAA"));
38 assert!(parsed.ends_with("BBBB"));
39 assert!(!parsed.starts_with("BBBB"));
40
41 // IDs are copied when assigned.
42 let mut switched = parsed;
43 assert_eq!(switched, parsed);
44
45 // Validity can be checked, and a "marker" exists for null / invalid IDs.
46 assert!(switched.is_valid());
47 assert!(!switched.is_null());
48 assert_ne!(switched, TinyId::null());
49 // Mutable IDs can be made null. This change has no effect on the `parsed` variable.
50 switched.make_null();
51 assert!(!switched.is_valid());
52 assert!(switched.is_null());
53 assert_eq!(switched, TinyId::null());
54}
Sourcepub fn is_valid(self) -> bool
pub fn is_valid(self) -> bool
Checks whether this TinyId
is null or has any invalid bytes.
Examples found in repository?
5fn main() {
6 // Create a random ID
7 let rand_id = TinyId::random();
8
9 // Parse a string into a Result<TinyId, TinyIdError> for possibly unsafe / invalid ID strings
10 let maybe = TinyId::from_str("AAAABBBB");
11 assert!(maybe.is_ok());
12 let bad = TinyId::from_str("AAAABBB");
13 assert!(bad.is_err());
14
15 // Parse a string you **KNOW** is safe into a TinyId
16 let parsed = TinyId::from_str_unchecked("AAAABBBB");
17
18 // All expected operations are available on TinyIds
19 // Equality is a simple byte comparison so it should be fast and cheap!
20 assert_eq!(maybe.unwrap(), parsed);
21
22 // IDs may be printed using Display or Debug
23 println!("Random ID: {rand_id}");
24 println!("Parsed ID: {parsed}");
25 println!(" Debug ID: {parsed:?}");
26
27 // IDs are small!
28 println!("TinyID Size: {}", std::mem::size_of::<TinyId>());
29
30 // IDs are case-sensitive
31 let parsed2 = TinyId::from_str_unchecked("aaaaBBBB");
32 assert_ne!(parsed, parsed2);
33
34 // Check whether an ID starts with a given string. Example use case would be providing a
35 // list of IDs to a user, and asking for a partial string to match against so the user
36 // doesn't have to type the entire thing.
37 assert!(parsed.starts_with("AAAA"));
38 assert!(parsed.ends_with("BBBB"));
39 assert!(!parsed.starts_with("BBBB"));
40
41 // IDs are copied when assigned.
42 let mut switched = parsed;
43 assert_eq!(switched, parsed);
44
45 // Validity can be checked, and a "marker" exists for null / invalid IDs.
46 assert!(switched.is_valid());
47 assert!(!switched.is_null());
48 assert_ne!(switched, TinyId::null());
49 // Mutable IDs can be made null. This change has no effect on the `parsed` variable.
50 switched.make_null();
51 assert!(!switched.is_valid());
52 assert!(switched.is_null());
53 assert_eq!(switched, TinyId::null());
54}
Sourcepub fn is_null(self) -> bool
pub fn is_null(self) -> bool
Checks whether this TinyId
is null.
Examples found in repository?
5fn main() {
6 // Create a random ID
7 let rand_id = TinyId::random();
8
9 // Parse a string into a Result<TinyId, TinyIdError> for possibly unsafe / invalid ID strings
10 let maybe = TinyId::from_str("AAAABBBB");
11 assert!(maybe.is_ok());
12 let bad = TinyId::from_str("AAAABBB");
13 assert!(bad.is_err());
14
15 // Parse a string you **KNOW** is safe into a TinyId
16 let parsed = TinyId::from_str_unchecked("AAAABBBB");
17
18 // All expected operations are available on TinyIds
19 // Equality is a simple byte comparison so it should be fast and cheap!
20 assert_eq!(maybe.unwrap(), parsed);
21
22 // IDs may be printed using Display or Debug
23 println!("Random ID: {rand_id}");
24 println!("Parsed ID: {parsed}");
25 println!(" Debug ID: {parsed:?}");
26
27 // IDs are small!
28 println!("TinyID Size: {}", std::mem::size_of::<TinyId>());
29
30 // IDs are case-sensitive
31 let parsed2 = TinyId::from_str_unchecked("aaaaBBBB");
32 assert_ne!(parsed, parsed2);
33
34 // Check whether an ID starts with a given string. Example use case would be providing a
35 // list of IDs to a user, and asking for a partial string to match against so the user
36 // doesn't have to type the entire thing.
37 assert!(parsed.starts_with("AAAA"));
38 assert!(parsed.ends_with("BBBB"));
39 assert!(!parsed.starts_with("BBBB"));
40
41 // IDs are copied when assigned.
42 let mut switched = parsed;
43 assert_eq!(switched, parsed);
44
45 // Validity can be checked, and a "marker" exists for null / invalid IDs.
46 assert!(switched.is_valid());
47 assert!(!switched.is_null());
48 assert_ne!(switched, TinyId::null());
49 // Mutable IDs can be made null. This change has no effect on the `parsed` variable.
50 switched.make_null();
51 assert!(!switched.is_valid());
52 assert!(switched.is_null());
53 assert_eq!(switched, TinyId::null());
54}
Sourcepub fn make_null(&mut self)
pub fn make_null(&mut self)
Makes this TinyId
null.
Examples found in repository?
5fn main() {
6 // Create a random ID
7 let rand_id = TinyId::random();
8
9 // Parse a string into a Result<TinyId, TinyIdError> for possibly unsafe / invalid ID strings
10 let maybe = TinyId::from_str("AAAABBBB");
11 assert!(maybe.is_ok());
12 let bad = TinyId::from_str("AAAABBB");
13 assert!(bad.is_err());
14
15 // Parse a string you **KNOW** is safe into a TinyId
16 let parsed = TinyId::from_str_unchecked("AAAABBBB");
17
18 // All expected operations are available on TinyIds
19 // Equality is a simple byte comparison so it should be fast and cheap!
20 assert_eq!(maybe.unwrap(), parsed);
21
22 // IDs may be printed using Display or Debug
23 println!("Random ID: {rand_id}");
24 println!("Parsed ID: {parsed}");
25 println!(" Debug ID: {parsed:?}");
26
27 // IDs are small!
28 println!("TinyID Size: {}", std::mem::size_of::<TinyId>());
29
30 // IDs are case-sensitive
31 let parsed2 = TinyId::from_str_unchecked("aaaaBBBB");
32 assert_ne!(parsed, parsed2);
33
34 // Check whether an ID starts with a given string. Example use case would be providing a
35 // list of IDs to a user, and asking for a partial string to match against so the user
36 // doesn't have to type the entire thing.
37 assert!(parsed.starts_with("AAAA"));
38 assert!(parsed.ends_with("BBBB"));
39 assert!(!parsed.starts_with("BBBB"));
40
41 // IDs are copied when assigned.
42 let mut switched = parsed;
43 assert_eq!(switched, parsed);
44
45 // Validity can be checked, and a "marker" exists for null / invalid IDs.
46 assert!(switched.is_valid());
47 assert!(!switched.is_null());
48 assert_ne!(switched, TinyId::null());
49 // Mutable IDs can be made null. This change has no effect on the `parsed` variable.
50 switched.make_null();
51 assert!(!switched.is_valid());
52 assert!(switched.is_null());
53 assert_eq!(switched, TinyId::null());
54}
Sourcepub fn from_str_unchecked(s: &str) -> Self
pub fn from_str_unchecked(s: &str) -> Self
Examples found in repository?
5fn main() {
6 // Create a random ID
7 let rand_id = TinyId::random();
8
9 // Parse a string into a Result<TinyId, TinyIdError> for possibly unsafe / invalid ID strings
10 let maybe = TinyId::from_str("AAAABBBB");
11 assert!(maybe.is_ok());
12 let bad = TinyId::from_str("AAAABBB");
13 assert!(bad.is_err());
14
15 // Parse a string you **KNOW** is safe into a TinyId
16 let parsed = TinyId::from_str_unchecked("AAAABBBB");
17
18 // All expected operations are available on TinyIds
19 // Equality is a simple byte comparison so it should be fast and cheap!
20 assert_eq!(maybe.unwrap(), parsed);
21
22 // IDs may be printed using Display or Debug
23 println!("Random ID: {rand_id}");
24 println!("Parsed ID: {parsed}");
25 println!(" Debug ID: {parsed:?}");
26
27 // IDs are small!
28 println!("TinyID Size: {}", std::mem::size_of::<TinyId>());
29
30 // IDs are case-sensitive
31 let parsed2 = TinyId::from_str_unchecked("aaaaBBBB");
32 assert_ne!(parsed, parsed2);
33
34 // Check whether an ID starts with a given string. Example use case would be providing a
35 // list of IDs to a user, and asking for a partial string to match against so the user
36 // doesn't have to type the entire thing.
37 assert!(parsed.starts_with("AAAA"));
38 assert!(parsed.ends_with("BBBB"));
39 assert!(!parsed.starts_with("BBBB"));
40
41 // IDs are copied when assigned.
42 let mut switched = parsed;
43 assert_eq!(switched, parsed);
44
45 // Validity can be checked, and a "marker" exists for null / invalid IDs.
46 assert!(switched.is_valid());
47 assert!(!switched.is_null());
48 assert_ne!(switched, TinyId::null());
49 // Mutable IDs can be made null. This change has no effect on the `parsed` variable.
50 switched.make_null();
51 assert!(!switched.is_valid());
52 assert!(switched.is_null());
53 assert_eq!(switched, TinyId::null());
54}
Sourcepub fn from_u64(n: u64) -> Result<Self, TinyIdError>
pub fn from_u64(n: u64) -> Result<Self, TinyIdError>
Attempt to create a new TinyId
from a u64.
§Errors
TinyIdError::InvalidLength
if the input is not 8 bytes long.TinyIdError::InvalidCharacters
if the input contains invalid chars/bytes.
Sourcepub fn from_u64_unchecked(n: u64) -> Self
pub fn from_u64_unchecked(n: u64) -> Self
Creates a new TinyId
from the given u64
, without validating
that the bytes are valid.
Sourcepub fn from_bytes(bytes: [u8; 8]) -> Result<Self, TinyIdError>
pub fn from_bytes(bytes: [u8; 8]) -> Result<Self, TinyIdError>
Attempt to create a new TinyId
from the given byte array.
§Errors
TinyIdError::InvalidCharacters
if the input contains invalid chars/bytes.
Sourcepub fn from_bytes_unchecked(bytes: [u8; 8]) -> Self
pub fn from_bytes_unchecked(bytes: [u8; 8]) -> Self
Creates a new TinyId
from the given [u8; 8]
, without validating
that the bytes are valid.
Sourcepub fn starts_with(&self, input: &str) -> bool
pub fn starts_with(&self, input: &str) -> bool
Checks whether this TinyId
starts with the given string. This converts self
to string so
any associated overhead is incurred.
Examples found in repository?
5fn main() {
6 // Create a random ID
7 let rand_id = TinyId::random();
8
9 // Parse a string into a Result<TinyId, TinyIdError> for possibly unsafe / invalid ID strings
10 let maybe = TinyId::from_str("AAAABBBB");
11 assert!(maybe.is_ok());
12 let bad = TinyId::from_str("AAAABBB");
13 assert!(bad.is_err());
14
15 // Parse a string you **KNOW** is safe into a TinyId
16 let parsed = TinyId::from_str_unchecked("AAAABBBB");
17
18 // All expected operations are available on TinyIds
19 // Equality is a simple byte comparison so it should be fast and cheap!
20 assert_eq!(maybe.unwrap(), parsed);
21
22 // IDs may be printed using Display or Debug
23 println!("Random ID: {rand_id}");
24 println!("Parsed ID: {parsed}");
25 println!(" Debug ID: {parsed:?}");
26
27 // IDs are small!
28 println!("TinyID Size: {}", std::mem::size_of::<TinyId>());
29
30 // IDs are case-sensitive
31 let parsed2 = TinyId::from_str_unchecked("aaaaBBBB");
32 assert_ne!(parsed, parsed2);
33
34 // Check whether an ID starts with a given string. Example use case would be providing a
35 // list of IDs to a user, and asking for a partial string to match against so the user
36 // doesn't have to type the entire thing.
37 assert!(parsed.starts_with("AAAA"));
38 assert!(parsed.ends_with("BBBB"));
39 assert!(!parsed.starts_with("BBBB"));
40
41 // IDs are copied when assigned.
42 let mut switched = parsed;
43 assert_eq!(switched, parsed);
44
45 // Validity can be checked, and a "marker" exists for null / invalid IDs.
46 assert!(switched.is_valid());
47 assert!(!switched.is_null());
48 assert_ne!(switched, TinyId::null());
49 // Mutable IDs can be made null. This change has no effect on the `parsed` variable.
50 switched.make_null();
51 assert!(!switched.is_valid());
52 assert!(switched.is_null());
53 assert_eq!(switched, TinyId::null());
54}
Sourcepub fn ends_with(&self, input: &str) -> bool
pub fn ends_with(&self, input: &str) -> bool
Checks whether this TinyId
ends with the given string. This converts self
to string so
any associated overhead is incurred.
Examples found in repository?
5fn main() {
6 // Create a random ID
7 let rand_id = TinyId::random();
8
9 // Parse a string into a Result<TinyId, TinyIdError> for possibly unsafe / invalid ID strings
10 let maybe = TinyId::from_str("AAAABBBB");
11 assert!(maybe.is_ok());
12 let bad = TinyId::from_str("AAAABBB");
13 assert!(bad.is_err());
14
15 // Parse a string you **KNOW** is safe into a TinyId
16 let parsed = TinyId::from_str_unchecked("AAAABBBB");
17
18 // All expected operations are available on TinyIds
19 // Equality is a simple byte comparison so it should be fast and cheap!
20 assert_eq!(maybe.unwrap(), parsed);
21
22 // IDs may be printed using Display or Debug
23 println!("Random ID: {rand_id}");
24 println!("Parsed ID: {parsed}");
25 println!(" Debug ID: {parsed:?}");
26
27 // IDs are small!
28 println!("TinyID Size: {}", std::mem::size_of::<TinyId>());
29
30 // IDs are case-sensitive
31 let parsed2 = TinyId::from_str_unchecked("aaaaBBBB");
32 assert_ne!(parsed, parsed2);
33
34 // Check whether an ID starts with a given string. Example use case would be providing a
35 // list of IDs to a user, and asking for a partial string to match against so the user
36 // doesn't have to type the entire thing.
37 assert!(parsed.starts_with("AAAA"));
38 assert!(parsed.ends_with("BBBB"));
39 assert!(!parsed.starts_with("BBBB"));
40
41 // IDs are copied when assigned.
42 let mut switched = parsed;
43 assert_eq!(switched, parsed);
44
45 // Validity can be checked, and a "marker" exists for null / invalid IDs.
46 assert!(switched.is_valid());
47 assert!(!switched.is_null());
48 assert_ne!(switched, TinyId::null());
49 // Mutable IDs can be made null. This change has no effect on the `parsed` variable.
50 switched.make_null();
51 assert!(!switched.is_valid());
52 assert!(switched.is_null());
53 assert_eq!(switched, TinyId::null());
54}