Skip to content

Commit

Permalink
Merge pull request #9 from zbraniecki/fix_alphanumeric
Browse files Browse the repository at this point in the history
Test for numbers in is_ascii_alphanumeric
  • Loading branch information
zbraniecki authored Aug 23, 2019
2 parents 5046730 + 72bbca7 commit 9b1e294
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 6 deletions.
28 changes: 24 additions & 4 deletions src/tinystr16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,35 @@ impl TinyStr16 {
unsafe { Self(NonZeroU128::new_unchecked(result)) }
}

pub fn is_ascii_alphabetic(self) -> bool {
let word = self.0.get();
let mask =
(word + 0x7f7f7f7f_7f7f7f7f_7f7f7f7f_7f7f7f7f) & 0x80808080_80808080_80808080_80808080;
let lower = word | 0x20202020_20202020_20202020_20202020;
let alpha = !(lower + 0x1f1f1f1f_1f1f1f1f_1f1f1f1f_1f1f1f1f)
| (lower + 0x05050505_05050505_05050505_05050505);
(alpha & mask) == 0
}

pub fn is_ascii_alphanumeric(self) -> bool {
let word = self.0.get();
let mask =
(word + 0x7f7f7f7f_7f7f7f7f_7f7f7f7f_7f7f7f7f) & 0x80808080_80808080_80808080_80808080;
let numeric = !(word + 0x50505050_50505050_50505050_50505050)
| (word + 0x46464646_46464646_46464646_46464646);
let lower = word | 0x20202020_20202020_20202020_20202020;
((!(lower + 0x1f1f1f1f_1f1f1f1f_1f1f1f1f_1f1f1f1f)
| (lower + 0x05050505_05050505_05050505_05050505))
& mask)
== 0
let alpha = !(lower + 0x1f1f1f1f_1f1f1f1f_1f1f1f1f_1f1f1f1f)
| (lower + 0x05050505_05050505_05050505_05050505);
(alpha & numeric & mask) == 0
}

pub fn is_ascii_numeric(self) -> bool {
let word = self.0.get();
let mask =
(word + 0x7f7f7f7f_7f7f7f7f_7f7f7f7f_7f7f7f7f) & 0x80808080_80808080_80808080_80808080;
let numeric = !(word + 0x50505050_50505050_50505050_50505050)
| (word + 0x46464646_46464646_46464646_46464646);
(numeric & mask) == 0
}

pub fn to_ascii_titlecase(self) -> Self {
Expand Down
19 changes: 18 additions & 1 deletion src/tinystr4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,28 @@ impl TinyStr4 {
unsafe { Self(NonZeroU32::new_unchecked(result)) }
}

pub fn is_ascii_alphabetic(self) -> bool {
let word = self.0.get();
let mask = (word + 0x7f7f_7f7f) & 0x8080_8080;
let lower = word | 0x2020_2020;
let alpha = !(lower + 0x1f1f_1f1f) | (lower + 0x0505_0505);
(alpha & mask) == 0
}

pub fn is_ascii_alphanumeric(self) -> bool {
let word = self.0.get();
let mask = (word + 0x7f7f_7f7f) & 0x8080_8080;
let numeric = !(word + 0x5050_5050) | (word + 0x4646_4646);
let lower = word | 0x2020_2020;
((!(lower + 0x1f1f_1f1f) | (lower + 0x0505_0505)) & mask) == 0
let alpha = !(lower + 0x1f1f_1f1f) | (lower + 0x0505_0505);
(alpha & numeric & mask) == 0
}

pub fn is_ascii_numeric(self) -> bool {
let word = self.0.get();
let mask = (word + 0x7f7f_7f7f) & 0x8080_8080;
let numeric = !(word + 0x5050_5050) | (word + 0x4646_4646);
(numeric & mask) == 0
}

/// Makes the string all lowercase except for the first character,
Expand Down
19 changes: 18 additions & 1 deletion src/tinystr8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,28 @@ impl TinyStr8 {
unsafe { Self(NonZeroU64::new_unchecked(result)) }
}

pub fn is_ascii_alphabetic(self) -> bool {
let word = self.0.get();
let mask = (word + 0x7f7f7f7f_7f7f7f7f) & 0x80808080_80808080;
let lower = word | 0x20202020_20202020;
let alpha = !(lower + 0x1f1f1f1f_1f1f1f1f) | (lower + 0x05050505_05050505);
(alpha & mask) == 0
}

pub fn is_ascii_alphanumeric(self) -> bool {
let word = self.0.get();
let mask = (word + 0x7f7f7f7f_7f7f7f7f) & 0x80808080_80808080;
let numeric = !(word + 0x50505050_50505050) | (word + 0x46464646_46464646);
let lower = word | 0x20202020_20202020;
((!(lower + 0x1f1f1f1f_1f1f1f1f) | (lower + 0x05050505_05050505)) & mask) == 0
let alpha = !(lower + 0x1f1f1f1f_1f1f1f1f) | (lower + 0x05050505_05050505);
(alpha & numeric & mask) == 0
}

pub fn is_ascii_numeric(self) -> bool {
let word = self.0.get();
let mask = (word + 0x7f7f7f7f_7f7f7f7f) & 0x80808080_80808080;
let numeric = !(word + 0x50505050_50505050) | (word + 0x46464646_46464646);
(numeric & mask) == 0
}

pub fn to_ascii_titlecase(self) -> Self {
Expand Down
51 changes: 51 additions & 0 deletions tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,23 @@ fn tiny4_nonascii() {
#[test]
fn tiny4_alpha() {
let s: TinyStr4 = "@aZ[".parse().unwrap();
assert!(!s.is_ascii_alphabetic());
assert!(!s.is_ascii_alphanumeric());
assert_eq!(s.to_ascii_uppercase().as_str(), "@AZ[");
assert_eq!(s.to_ascii_lowercase().as_str(), "@az[");

assert!("abYZ".parse::<TinyStr4>().unwrap().is_ascii_alphabetic());
assert!("abYZ".parse::<TinyStr4>().unwrap().is_ascii_alphanumeric());
assert!("a123".parse::<TinyStr4>().unwrap().is_ascii_alphanumeric());
assert!(!"a123".parse::<TinyStr4>().unwrap().is_ascii_alphabetic());
}

#[test]
fn tiny4_numeric() {
let s: TinyStr4 = "@aZ[".parse().unwrap();
assert!(!s.is_ascii_numeric());

assert!("0123".parse::<TinyStr4>().unwrap().is_ascii_numeric());
}

#[test]
Expand Down Expand Up @@ -168,14 +180,29 @@ fn tiny8_nonascii() {
#[test]
fn tiny8_alpha() {
let s: TinyStr8 = "@abcXYZ[".parse().unwrap();
assert!(!s.is_ascii_alphabetic());
assert!(!s.is_ascii_alphanumeric());
assert_eq!(s.to_ascii_uppercase().as_str(), "@ABCXYZ[");
assert_eq!(s.to_ascii_lowercase().as_str(), "@abcxyz[");

assert!("abcXYZ".parse::<TinyStr8>().unwrap().is_ascii_alphabetic());
assert!("abcXYZ"
.parse::<TinyStr8>()
.unwrap()
.is_ascii_alphanumeric());
assert!(!"abc123".parse::<TinyStr8>().unwrap().is_ascii_alphabetic());
assert!("abc123"
.parse::<TinyStr8>()
.unwrap()
.is_ascii_alphanumeric());
}

#[test]
fn tiny8_numeric() {
let s: TinyStr8 = "@abcXYZ[".parse().unwrap();
assert!(!s.is_ascii_numeric());

assert!("01234567".parse::<TinyStr8>().unwrap().is_ascii_numeric());
}

#[test]
Expand Down Expand Up @@ -303,16 +330,40 @@ fn tiny16_nonascii() {
#[test]
fn tiny16_alpha() {
let s: TinyStr16 = "@abcdefgTUVWXYZ[".parse().unwrap();
assert!(!s.is_ascii_alphabetic());
assert!(!s.is_ascii_alphanumeric());
assert_eq!(s.to_ascii_uppercase().as_str(), "@ABCDEFGTUVWXYZ[");
assert_eq!(s.to_ascii_lowercase().as_str(), "@abcdefgtuvwxyz[");

assert!("abcdefgTUVWXYZ"
.parse::<TinyStr16>()
.unwrap()
.is_ascii_alphabetic());
assert!("abcdefgTUVWXYZ"
.parse::<TinyStr16>()
.unwrap()
.is_ascii_alphanumeric());
assert!(!"abcdefg0123456"
.parse::<TinyStr16>()
.unwrap()
.is_ascii_alphabetic());
assert!("abcdefgTUVWXYZ"
.parse::<TinyStr16>()
.unwrap()
.is_ascii_alphanumeric());
}

#[test]
fn tiny16_numeric() {
let s: TinyStr16 = "@abcdefgTUVWXYZ[".parse().unwrap();
assert!(!s.is_ascii_numeric());

assert!("0123456789"
.parse::<TinyStr16>()
.unwrap()
.is_ascii_numeric());
}

#[test]
fn tiny16_titlecase() {
assert_eq!(
Expand Down

0 comments on commit 9b1e294

Please sign in to comment.