Skip to content

Commit

Permalink
fix: handle 0-length cuids
Browse files Browse the repository at this point in the history
  • Loading branch information
mplanchard committed Aug 3, 2021
1 parent 199f299 commit a4fca2f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 9 deletions.
29 changes: 20 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,19 @@ pub fn slug() -> Result<String, CuidError> {
/// let id = cuid::cuid().unwrap();
/// assert!(cuid::is_cuid(id));
/// ```
pub fn is_cuid<S: Into<String>>(to_check: S) -> bool {
&to_check.into()[..1] == START_STR
pub fn is_cuid<S: AsRef<str>>(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
Expand All @@ -145,9 +156,9 @@ pub fn is_cuid<S: Into<String>>(to_check: S) -> bool {
/// let slug = cuid::slug().unwrap();
/// assert!(cuid::is_slug(slug));
/// ```
pub fn is_slug<S: Into<String>>(to_check: S) -> bool {
let length = to_check.into().len();
(7..=10).contains(&length)
pub fn is_slug<S: AsRef<str>>(to_check: S) -> bool {
// the slug will always be 10 characters
to_check.as_ref().len() == 10
}

#[cfg(test)]
Expand All @@ -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]
Expand Down
2 changes: 2 additions & 0 deletions src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
31 changes: 31 additions & 0 deletions tests/length.rs
Original file line number Diff line number Diff line change
@@ -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));
}

0 comments on commit a4fca2f

Please sign in to comment.