use_accessible_label/
lib.rs1#![forbid(unsafe_code)]
2#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct AccessibleLabel {
28 text: String,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum AccessibleLabelError {
33 EmptyLabel,
34 InvalidMaxWords,
35}
36
37#[must_use]
38pub fn normalize_accessible_label(label: &str) -> String {
39 label.split_whitespace().collect::<Vec<_>>().join(" ")
40}
41
42#[must_use]
43pub fn has_accessible_label(label: &str) -> bool {
44 !normalize_accessible_label(label).is_empty()
45}
46
47#[must_use]
48pub fn label_word_count(label: &str) -> usize {
49 normalize_accessible_label(label).split_whitespace().count()
50}
51
52impl AccessibleLabel {
53 pub fn new(text: impl Into<String>) -> Result<Self, AccessibleLabelError> {
54 let text = normalize_accessible_label(&text.into());
55
56 if text.is_empty() {
57 return Err(AccessibleLabelError::EmptyLabel);
58 }
59
60 Ok(Self { text })
61 }
62
63 #[must_use]
64 pub fn text(&self) -> &str {
65 self.text.as_str()
66 }
67
68 #[must_use]
69 pub fn is_empty(&self) -> bool {
70 self.text.is_empty()
71 }
72
73 #[must_use]
74 pub fn word_count(&self) -> usize {
75 self.text.split_whitespace().count()
76 }
77}
78
79pub fn is_label_too_long(label: &str, max_words: usize) -> Result<bool, AccessibleLabelError> {
80 if !has_accessible_label(label) {
81 return Err(AccessibleLabelError::EmptyLabel);
82 }
83
84 if max_words == 0 {
85 return Err(AccessibleLabelError::InvalidMaxWords);
86 }
87
88 Ok(label_word_count(label) > max_words)
89}
90
91#[cfg(test)]
92mod tests {
93 use super::{
94 AccessibleLabel, AccessibleLabelError, has_accessible_label, is_label_too_long,
95 label_word_count, normalize_accessible_label,
96 };
97
98 #[test]
99 fn normalizes_and_counts_labels() {
100 let label = AccessibleLabel::new(" Submit order ").unwrap();
101
102 assert_eq!(label.text(), "Submit order");
103 assert!(!label.is_empty());
104 assert_eq!(label.word_count(), 2);
105 assert!(has_accessible_label(" Submit order "));
106 assert_eq!(
107 normalize_accessible_label(" Submit order "),
108 "Submit order"
109 );
110 assert_eq!(label_word_count("Submit order now"), 3);
111 }
112
113 #[test]
114 fn rejects_empty_labels_and_checks_length() {
115 assert_eq!(
116 AccessibleLabel::new(" "),
117 Err(AccessibleLabelError::EmptyLabel)
118 );
119 assert_eq!(
120 is_label_too_long(" ", 3),
121 Err(AccessibleLabelError::EmptyLabel)
122 );
123 assert_eq!(
124 is_label_too_long("Submit order now", 0),
125 Err(AccessibleLabelError::InvalidMaxWords)
126 );
127 assert!(is_label_too_long("Submit order now", 2).unwrap());
128 assert!(!is_label_too_long("Submit order", 3).unwrap());
129 }
130}