1pub fn is_palindrome(s: &str) -> bool {
2 let cleaned: String = s.chars().filter(|c| c.is_alphanumeric()).collect();
3 let reversed: String = cleaned.chars().rev().collect();
4 cleaned.eq_ignore_ascii_case(&reversed)
5}
6
7pub fn capitalize_first(s: &str) -> String {
8 s.split_whitespace()
9 .map(|word| {
10 let mut chars = word.chars();
11 match chars.next() {
12 None => String::new(),
13 Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
14 }
15 })
16 .collect::<Vec<_>>()
17 .join(" ")
18}
19
20#[cfg(test)]
21mod tests {
22 use super::*;
23
24 #[test]
25 fn test_is_palindrome() {
26 assert!(is_palindrome("A man, a plan, a canal, Panama!"));
27 }
28
29 #[test]
30 fn test_capitalize_first() {
31 assert_eq!(capitalize_first("hello world"), "Hello World");
32 }
33}