diff --git a/src/lib.rs b/src/lib.rs index 2cfbf2a..271dfa6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -132,8 +132,19 @@ pub fn slug() -> Result { /// let id = cuid::cuid().unwrap(); /// assert!(cuid::is_cuid(id)); /// ``` -pub fn is_cuid>(to_check: S) -> bool { - &to_check.into()[..1] == START_STR +pub fn is_cuid>(to_check: S) -> bool { + let to_check = to_check.as_ref(); + match to_check.len() { + // the CUID length will increase as the timestamp increases. The + // timestamp portion currently represents 8 characters. It has the + // potential to increase to up to 15 characters when the timestamp + // reaches the maximum 64-bit integer, at which point the earth will be + // long gone, presumably along with this code. At that time, the CUID + // length would be 32. 9 characters gives us up through at least the + // year 5138, though, so checking for 25 or 26 characters should do it. + 25..=26 => &to_check[..1] == START_STR, + _ => false, + } } /// Return whether a string is a legitimate CUID slug @@ -145,9 +156,9 @@ pub fn is_cuid>(to_check: S) -> bool { /// let slug = cuid::slug().unwrap(); /// assert!(cuid::is_slug(slug)); /// ``` -pub fn is_slug>(to_check: S) -> bool { - let length = to_check.into().len(); - (7..=10).contains(&length) +pub fn is_slug>(to_check: S) -> bool { + // the slug will always be 10 characters + to_check.as_ref().len() == 10 } #[cfg(test)] @@ -170,13 +181,13 @@ mod tests { } #[test] - fn slug_max_len() { - assert!(slug().unwrap().len() <= 10); + fn cuid_is_not_cuid_zero_len() { + assert_eq!(is_cuid(""), false); } #[test] - fn slug_min_len() { - assert!(slug().unwrap().len() >= 7); + fn slug_len() { + assert!(slug().unwrap().len() == 10); } #[test] diff --git a/src/time.rs b/src/time.rs index f77814a..6329e17 100644 --- a/src/time.rs +++ b/src/time.rs @@ -16,6 +16,8 @@ mod time_tests { use super::super::BASE; use super::*; + // NOTE: this will start failing in ~2059, at which point this will need to + // be updated to 9 #[test] fn test_timestamp_len() { assert_eq!(timestamp().unwrap().len(), 8); diff --git a/tests/length.rs b/tests/length.rs new file mode 100644 index 0000000..9a29f4a --- /dev/null +++ b/tests/length.rs @@ -0,0 +1,31 @@ +//! Test that CUIDs are of a predictable length + +use cuid; + +use std::collections::HashSet; + +#[test] +fn check_cuid_length() { + let mut set = HashSet::new(); + for _ in 0..100000 { + let id = cuid::cuid().unwrap(); + set.insert(id); + } + // all CUIDs are of the same length + // NOTE: this will start failing in ~2059, at which poit this will need to + // be updated to 26 + assert!(set.iter().all(|i| i.len() == 25)); +} + +#[test] +fn check_cuid_slug_length() { + let mut set = HashSet::new(); + for _ in 0..100000 { + let id = cuid::slug().unwrap(); + set.insert(id); + } + // all slugs are of the same length + // NOTE: this will start failing in ~2059, at which poit this will need to + // be updated to 26 + assert!(set.iter().all(|i| i.len() == 10)); +}