use std::borrow::Cow;
pub const BOM_REMOVAL_HINT: &str = concat!(
"remove the U+FEFF byte at this position; ",
"if the file is a concatenation of two BOM-prefixed exports, ",
"strip BOMs from the inner files before concatenating",
);
#[must_use]
pub fn normalize_date_str(s: &str) -> Cow<'_, str> {
if !s.contains('/') && s.len() == 10 {
return Cow::Borrowed(s);
}
let s = s.replace('/', "-");
if let Some((year, rest)) = s.split_once('-')
&& let Some((month, day)) = rest.split_once('-')
{
return Cow::Owned(format!("{year}-{month:0>2}-{day:0>2}"));
}
Cow::Owned(s)
}
#[must_use]
pub fn describe_invalid_date(s: &str) -> String {
let parts: Vec<&str> = s.split(['-', '/']).collect();
if parts.len() == 3
&& let (Ok(year), Ok(month), Ok(day)) = (
parts[0].parse::<i32>(),
parts[1].parse::<u32>(),
parts[2].parse::<u32>(),
)
{
if !(1..=12).contains(&month) {
return format!("month {month} out of range");
}
let year_month = format!("{year}-{month:02}");
return format!("day {day} out of range for {year_month}");
}
format!("invalid date '{s}'")
}
#[must_use]
pub fn find_unicode_account(text: &str) -> Option<&str> {
for token in text.split_whitespace() {
if !token.contains(':') {
continue;
}
let first_char = token.chars().next().unwrap_or(' ');
if !first_char.is_uppercase() {
continue;
}
if !token.is_ascii() {
return Some(token);
}
}
None
}