1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum AsciiKind {
6 Alphabetic,
7 Numeric,
8 Alphanumeric,
9 Whitespace,
10 Control,
11 Punctuation,
12 Other,
13}
14
15#[must_use]
16pub fn is_ascii(input: &str) -> bool {
17 input.is_ascii()
18}
19
20#[must_use]
21pub fn is_ascii_alpha(input: &str) -> bool {
22 !input.is_empty()
23 && input
24 .chars()
25 .all(|character| character.is_ascii_alphabetic())
26}
27
28#[must_use]
29pub fn is_ascii_numeric(input: &str) -> bool {
30 !input.is_empty() && input.chars().all(|character| character.is_ascii_digit())
31}
32
33#[must_use]
34pub fn is_ascii_alphanumeric(input: &str) -> bool {
35 !input.is_empty()
36 && input
37 .chars()
38 .all(|character| character.is_ascii_alphanumeric())
39}
40
41#[must_use]
42pub fn is_ascii_whitespace_only(input: &str) -> bool {
43 !input.is_empty()
44 && input
45 .chars()
46 .all(|character| character.is_ascii_whitespace())
47}
48
49#[must_use]
50pub fn contains_non_ascii(input: &str) -> bool {
51 !input.is_ascii()
52}
53
54#[must_use]
55pub fn strip_non_ascii(input: &str) -> String {
56 input
57 .chars()
58 .filter(|character| character.is_ascii())
59 .collect()
60}
61
62#[must_use]
63pub fn replace_non_ascii(input: &str, replacement: char) -> String {
64 input
65 .chars()
66 .map(|character| {
67 if character.is_ascii() {
68 character
69 } else {
70 replacement
71 }
72 })
73 .collect()
74}
75
76#[must_use]
77pub fn ascii_kind(c: char) -> AsciiKind {
78 if !c.is_ascii() {
79 return AsciiKind::Other;
80 }
81
82 if c.is_ascii_alphabetic() {
83 return AsciiKind::Alphabetic;
84 }
85
86 if c.is_ascii_digit() {
87 return AsciiKind::Numeric;
88 }
89
90 if c.is_ascii_alphanumeric() {
91 return AsciiKind::Alphanumeric;
92 }
93
94 if c.is_ascii_whitespace() {
95 return AsciiKind::Whitespace;
96 }
97
98 if c.is_ascii_control() {
99 return AsciiKind::Control;
100 }
101
102 if c.is_ascii_punctuation() {
103 return AsciiKind::Punctuation;
104 }
105
106 AsciiKind::Other
107}