2024-11-04 18:46:56 +01:00
|
|
|
pub trait Capitalize {
|
2024-09-18 19:50:38 +02:00
|
|
|
fn capitalize(&self) -> String;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Implement the Capitalize trait for &str
|
2025-05-26 10:43:03 +02:00
|
|
|
impl<T: AsRef<str>> Capitalize for T {
|
2024-09-18 19:50:38 +02:00
|
|
|
fn capitalize(&self) -> String {
|
2025-05-26 10:43:03 +02:00
|
|
|
let s = self.as_ref();
|
|
|
|
|
let mut chars = s.chars();
|
|
|
|
|
let first = chars
|
|
|
|
|
.next()
|
2025-05-13 21:50:08 +02:00
|
|
|
.map(|c| c.to_uppercase().collect::<String>())
|
|
|
|
|
.unwrap_or_default();
|
|
|
|
|
let rest = chars.as_str().to_lowercase();
|
|
|
|
|
first + &rest
|
2024-09-18 19:50:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-14 17:51:33 +01:00
|
|
|
pub fn get_trimmed_string(value: &Option<String>) -> Option<String> {
|
|
|
|
|
if let Some(v) = value {
|
|
|
|
|
let trimmed = v.trim();
|
|
|
|
|
if !trimmed.is_empty() {
|
|
|
|
|
return Some(trimmed.to_string());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
None
|
2025-03-10 13:28:22 +01:00
|
|
|
}
|
2025-04-28 19:52:59 +02:00
|
|
|
|
|
|
|
|
pub fn generate_random_string(length: usize) -> String {
|
|
|
|
|
let charset = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
2025-06-27 18:44:28 +02:00
|
|
|
let range = ..charset.len();
|
2025-04-28 19:52:59 +02:00
|
|
|
let random_string: String = (0..length)
|
|
|
|
|
.map(|_| {
|
2025-06-27 18:44:28 +02:00
|
|
|
let idx = fastrand::usize(range);
|
2025-04-28 19:52:59 +02:00
|
|
|
charset[idx] as char
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
random_string
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-25 18:11:36 +02:00
|
|
|
// compare 2 small vecs without HashSet
|
|
|
|
|
pub fn small_vecs_equal_unordered<T: PartialEq>(a: &[T], b: &[T]) -> bool {
|
|
|
|
|
if a.len() != b.len() {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for item in a {
|
|
|
|
|
if !b.iter().any(|x| x == item) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-04 21:52:55 +02:00
|
|
|
pub fn get_non_empty_str<'a>(first: &'a str, second: &'a str, third: &'a str) -> &'a str {
|
|
|
|
|
if !first.is_empty() {
|
|
|
|
|
first
|
|
|
|
|
} else if !second.is_empty() {
|
|
|
|
|
second
|
|
|
|
|
} else {
|
|
|
|
|
third
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-28 19:52:59 +02:00
|
|
|
#[cfg(test)]
|
|
|
|
|
mod test {
|
|
|
|
|
use std::collections::HashSet;
|
2025-06-24 01:06:25 +02:00
|
|
|
use crate::utils::Capitalize;
|
2025-06-19 13:22:43 +02:00
|
|
|
use super::generate_random_string;
|
2025-04-28 19:52:59 +02:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_generate_random_string() {
|
|
|
|
|
let mut strings = HashSet::new();
|
|
|
|
|
for _i in 0..100 {
|
|
|
|
|
strings.insert(generate_random_string(5));
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(strings.len(), 100);
|
|
|
|
|
}
|
2025-05-15 11:15:18 +02:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_capitalize() {
|
|
|
|
|
assert_eq!("hELLO".capitalize(), "Hello");
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-28 19:52:59 +02:00
|
|
|
}
|