We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Ground Rules: Values, Types, Control Flow step 9 of 24
bool and char
Classify each Unicode scalar value in a string, preserving its order.
pub fn char_kinds(text: &str) -> Vec<String>
Iterate with text.chars() and apply these checks in order:
| First matching check | Output label |
|---|---|
is_ascii_digit() |
"digit" |
is_alphabetic() |
"alpha" |
is_whitespace() |
"space" |
| None of the above | "other" |
Return one owned String per scalar value. Empty input produces an empty
vector. For example, "a1 é" gives ["alpha", "digit", "space", "alpha"].
Bytes, scalar values and visible characters
A Rust char holds one Unicode scalar value and occupies four bytes.
Scalar values range from U+0000 to U+10FFFF, excluding the surrogate
range U+D800..=U+DFFF used in UTF-16 encoding. A str instead stores
UTF-8, where each scalar value uses one to four bytes:
fn main() {
let text = "a1 é";
assert_eq!(text.len(), 5); // UTF-8 bytes
assert_eq!(text.chars().count(), 4);
assert_eq!(size_of::<char>(), 4);
assert_eq!('é'.len_utf8(), 2);
assert_eq!('語'.len_utf8(), 3);
assert_eq!('🦀'.len_utf8(), 4);
}
.bytes() would visit the two UTF-8 bytes of é separately. This task
classifies the decoded scalar value, so use .chars().
A scalar value is not always a whole visible character. A letter and a combining accent can display together while remaining two scalar values. Some emoji sequences also contain several. This exercise does not group grapheme clusters or normalize different spellings of the same visible text:
fn main() {
let composed = "é";
let decomposed = "e\u{301}";
assert_eq!(composed.chars().count(), 1);
assert_eq!(decomposed.chars().count(), 2);
assert_eq!(decomposed.chars().collect::<Vec<_>>(), ['e', '\u{301}']);
}
The first string produces ["alpha"]; the second produces
["alpha", "other"]. That specific combining accent is not alphabetic;
do not assume every combining mark has the same Unicode properties.
Use the specified predicates
is_ascii_digit accepts only 0 through 9. is_numeric is broader and
would change the task: Arabic-Indic ٣ is numeric but receives "other"
here. Roman numeral Ⅳ is both numeric and alphabetic, so it receives
"alpha" under these rules.
is_alphabetic uses Unicode's Alphabetic property, which includes more
than ASCII letters. is_whitespace uses its White_Space property, covering
tabs, newlines and non-breaking space. A zero-width space (U+200B) does
not satisfy that predicate and receives "other".
Conditions are already booleans
Each predicate returns a bool. Use it directly in an if condition;
writing == true is redundant. Rust requires a boolean condition, so
if 1 is a type error (E0308). For a numeric condition, write the comparison
you intend, such as count != 0.
Explicit boolean-to-integer conversion is allowed when needed:
fn main() {
let has_digit = '7'.is_ascii_digit();
let label = if has_digit { "digit" } else { "other" };
assert_eq!(label, "digit");
assert_eq!(u8::from(has_digit), 1);
assert_eq!(u8::from(false), 0);
}
The starter triggers Clippy's default bool_comparison warning and omits
the whitespace branch. Fix both. Removing == true simplifies the source;
it is not a claim that the original emits an extra machine instruction.
Related default Clippy warnings include needless_bool, for expressions
such as if condition { true } else { false }, and char_lit_as_u8, for
character literals cast to bytes. For an ASCII byte, write b'A' directly.
Casting a non-ASCII char to u8 is not UTF-8 encoding.
Build each label with an if/else if chain returning &str, then call
to_string() when adding it to the output. No formatting is needed.
Submissions must compile, pass the tests and pass Clippy with warnings
treated as errors.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.