use std::borrow::Cow;
pub fn format_time_ms_to_timestamp_string(time_ms: f32) -> String {
let total_ms = time_ms.max(0.0) as i32;
let minute = total_ms / 60000;
let second = (total_ms % 60000) / 1000;
let ms = total_ms % 1000;
format!("{:02}:{:02}.{:03}", minute, second, ms)
}
pub fn is_number(s: &str) -> bool {
!s.is_empty() && s.chars().all(|c| c.is_ascii_digit())
}
pub fn remove_front_back_brackets(s: &str) -> String {
let s = s.trim();
for (open, close) in [('(', ')'), ('(', ')')] {
if let Some(inner) = s.strip_prefix(open).and_then(|s| s.strip_suffix(close)) {
return inner.to_string();
}
}
s.to_string()
}
pub fn compute_text_same(text_x: &str, text_y: &str, is_case_sensitive: bool) -> f64 {
let (text_x, text_y): (Cow<str>, Cow<str>) = if is_case_sensitive {
(text_x.into(), text_y.into())
} else {
(text_x.to_lowercase().into(), text_y.to_lowercase().into())
};
if text_x == text_y {
return 100.0;
}
let max_len = text_x.chars().count().max(text_y.chars().count()) as f64;
(lcs_length(&text_x, &text_y) as f64 / max_len) * 100.0
}
pub fn lcs_length(x: &str, y: &str) -> usize {
let x_chars: Vec<char> = x.chars().collect();
let y_chars: Vec<char> = y.chars().collect();
let m = x_chars.len();
let n = y_chars.len();
let mut prev = vec![0usize; n + 1];
let mut curr = vec![0usize; n + 1];
for i in 1..=m {
for j in 1..=n {
if x_chars[i - 1] == y_chars[j - 1] {
curr[j] = prev[j - 1] + 1;
} else {
curr[j] = prev[j].max(curr[j - 1]);
}
}
std::mem::swap(&mut prev, &mut curr);
}
prev[n]
}
pub fn is_chinese_or_japanese_character(character: char) -> bool {
matches!(character,
'\u{4E00}'..='\u{9FFF}'
| '\u{3400}'..='\u{4DBF}'
| '\u{3040}'..='\u{309F}'
| '\u{30A0}'..='\u{30FF}'
| '\u{31F0}'..='\u{31FF}')
}
pub fn has_chinese(s: &str) -> bool {
s.chars().any(|c| ('\u{4e00}'..='\u{9fff}').contains(&c))
}
pub fn collapse_whitespace(s: &str) -> String {
let mut result = String::with_capacity(s.len());
for part in s.split_whitespace() {
if !result.is_empty() {
result.push(' ');
}
result.push_str(part);
}
result
}
pub fn remove_duo_spaces(s: &str) -> String {
let mut result = String::with_capacity(s.len());
let mut last_was_space = false;
for c in s.chars() {
if c == ' ' {
if !last_was_space {
result.push(c);
}
last_was_space = true;
} else {
result.push(c);
last_was_space = false;
}
}
result
}