next_web_utils/common/
string.rs

1use rand::distributions::Alphanumeric;
2use rand::{thread_rng, Rng};
3
4/// `StringUtil` 是一个工具结构体,用于处理字符串相关的操作。
5pub struct StringUtil;
6
7impl StringUtil {
8
9    /// 空字符串。
10    /// 
11    pub const EMPTY: &'static str = "";
12
13    /// 生成指定长度的随机字母数字字符串 <button class="citation-flag" data-index="1">。
14    ///
15    /// # 参数
16    /// - `length`: 随机字符串的长度。
17    ///
18    /// # 返回值
19    /// 返回一个由 ASCII 字母和数字组成的随机字符串。
20    pub fn generate_random_string(length: usize) -> String {
21        let rand_string: String = thread_rng()
22            .sample_iter(&Alphanumeric)
23            .take(length)
24            .map(char::from)
25            .collect();
26        return rand_string;
27    }
28
29    /// 检查字符串是否为空或仅包含空白字符。
30    ///
31    /// # 参数
32    /// - `s`: 待检查的字符串。
33    ///
34    /// # 返回值
35    /// 如果字符串为空或仅包含空白字符,则返回 `true`;否则返回 `false`。
36    pub fn is_blank(s: &str) -> bool {
37        s.trim_end().is_empty()
38    }
39
40    /// 检查字符串是否非空且不全是空白字符。
41    ///
42    /// # 参数
43    /// - `s`: 待检查的字符串。
44    ///
45    /// # 返回值
46    /// 如果字符串非空且不全是空白字符,则返回 `true`;否则返回 `false`。
47    pub fn is_not_blank(s: &str) -> bool {
48        !StringUtil::is_blank(s)
49    }
50
51    /// 检查字符串是否仅包含数字字符。
52    ///
53    /// # 参数
54    /// - `s`: 待检查的字符串。
55    ///
56    /// # 返回值
57    /// 如果字符串仅包含数字字符,则返回 `true`;否则返回 `false`。
58    pub fn is_numeric(s: &str) -> bool {
59        s.chars().all(|c| c.is_numeric())
60    }
61
62    /// 检查字符串是否仅包含字母字符。
63    ///
64    /// # 参数
65    /// - `s`: 待检查的字符串。
66    ///
67    /// # 返回值
68    /// 如果字符串仅包含字母字符,则返回 `true`;否则返回 `false`。
69    pub fn is_alpha(s: &str) -> bool {
70        s.chars().all(|c| c.is_alphabetic())
71    }
72
73    /// 检查字符串是否为纯文本(仅包含字母数字字符或空白字符)。
74    ///
75    /// # 参数
76    /// - `s`: 待检查的字符串。
77    ///
78    /// # 返回值
79    /// 如果字符串为纯文本,则返回 `true`;否则返回 `false`。
80    pub fn is_text(s: &str) -> bool {
81        !s.trim().is_empty() && s.chars().all(|c| c.is_alphanumeric() || c.is_whitespace())
82    }
83
84    /// 对字符串进行 URL 编码。
85    ///
86    /// # 参数
87    /// - `input`: 待编码的字符串。
88    ///
89    /// # 返回值
90    /// 返回经过 URL 编码的字符串。
91    pub fn url_encode(input: &str) -> String {
92        let mut encoded = String::new();
93        for c in input.chars() {
94            if c.is_ascii_alphanumeric() || c == '-' || c == '_' || c == '.' || c == '~' {
95                encoded.push(c);
96            } else {
97                let mut buffer = [0; 4];
98                for &byte in c.encode_utf8(&mut buffer).as_bytes() {
99                    encoded.push('%');
100                    encoded.push_str(&format!("{:02X}", byte));
101                }
102            }
103        }
104        encoded
105    }
106
107    /// 截取字符串的一部分。
108    ///
109    /// # 参数
110    /// - `s`: 原始字符串。
111    /// - `start`: 起始索引(从 0 开始)。
112    /// - `end`: 结束索引(不包含该位置)。
113    ///
114    /// # 返回值
115    /// 返回截取后的子字符串。如果索引超出范围,则返回空字符串。
116    pub fn substring(s: &str, start: usize, end: usize) -> String {
117        s.chars()
118            .skip(start)
119            .take(end.saturating_sub(start))
120            .collect()
121    }
122
123    /// 反转字符串。
124    ///
125    /// # 参数
126    /// - `s`: 原始字符串。
127    ///
128    /// # 返回值
129    /// 返回反转后的字符串。
130    pub fn reverse(s: &str) -> String {
131        s.chars().rev().collect()
132    }
133
134    /// 将字符串转换为大写。
135    ///
136    /// # 参数
137    /// - `s`: 原始字符串。
138    ///
139    /// # 返回值
140    /// 返回转换为大写的字符串。
141    pub fn to_uppercase(s: &str) -> String {
142        s.to_uppercase()
143    }
144
145    /// 将字符串转换为小写。
146    ///
147    /// # 参数
148    /// - `s`: 原始字符串。
149    ///
150    /// # 返回值
151    /// 返回转换为小写的字符串。
152    pub fn to_lowercase(s: &str) -> String {
153        s.to_lowercase()
154    }
155
156    /// 去除字符串中的重复字符。
157    ///
158    /// # 参数
159    /// - `s`: 原始字符串。
160    ///
161    /// # 返回值
162    /// 返回去重后的字符串。
163    pub fn remove_duplicates(s: &str) -> String {
164        let mut seen = std::collections::HashSet::new();
165        s.chars().filter(|&c| seen.insert(c)).collect()
166    }
167
168    /// 检查字符串是否以指定前缀开头。
169    ///
170    /// # 参数
171    /// - `s`: 原始字符串。
172    /// - `prefix`: 待检查的前缀。
173    ///
174    /// # 返回值
175    /// 如果字符串以指定前缀开头,则返回 `true`;否则返回 `false`。
176    pub fn starts_with(s: &str, prefix: &str) -> bool {
177        s.starts_with(prefix)
178    }
179
180    /// 检查字符串是否以指定后缀结尾。
181    ///
182    /// # 参数
183    /// - `s`: 原始字符串。
184    /// - `suffix`: 待检查的后缀。
185    ///
186    /// # 返回值
187    /// 如果字符串以指定后缀结尾,则返回 `true`;否则返回 `false`。
188    pub fn ends_with(s: &str, suffix: &str) -> bool {
189        s.ends_with(suffix)
190    }
191
192    /// 检查字符串是否包含空白字符串。
193    ///
194    /// # 参数
195    /// - `s`: 原始字符串。
196    ///
197    /// # 返回值
198    /// 如果字符串包含空白,则返回 `true`;否则返回 `false`。
199    pub fn contains_whitespace(s: &str) -> bool {
200        s.chars().any(|c| c.is_whitespace())
201    }
202
203
204    /// 移除字符串中的指定前缀和后缀。
205    ///
206    /// # 参数
207    /// - `s`: 原始字符串。
208    /// - `prefix`: 待移除的前缀。
209    /// - `suffix`: 待移除的后缀。
210    ///
211    /// # 返回值
212    /// 返回移除前缀和后缀后的字符串。
213    pub fn remove_suffix(s: &str, suffix: &str) -> String {
214        if s.ends_with(suffix) {
215            s[..s.len() - suffix.len()].to_string()
216        } else {
217            s.to_string()
218        }
219    }
220
221    /// 移除字符串中的指定前缀。
222    ///
223    /// # 参数
224    /// - `s`: 原始字符串。
225    /// - `prefix`: 待移除的前缀。
226    ///
227    /// # 返回值
228    /// 返回移除前缀后的字符串。
229    pub fn remove_prefix(s: &str, prefix: &str) -> String {
230        if s.starts_with(prefix) {
231            s[prefix.len()..].to_string()
232        } else {
233            s.to_string()
234        }
235    }
236}