#[cfg(not(feature = "std"))]
use alloc::{format, string::String, vec::Vec};
#[cfg(feature = "std")]
use std::{format, string::String, vec::Vec};
use super::CoreError;
pub fn parse_ass_time(time_str: &str) -> Result<u32, CoreError> {
let parts: Vec<&str> = time_str.split(':').collect();
if parts.len() != 3 {
return Err(CoreError::InvalidTime(format!(
"Invalid time format: {time_str}"
)));
}
let hours: u32 = parts[0]
.parse()
.map_err(|_| CoreError::InvalidTime(format!("Invalid hours: {}", parts[0])))?;
let minutes: u32 = parts[1]
.parse()
.map_err(|_| CoreError::InvalidTime(format!("Invalid minutes: {}", parts[1])))?;
let seconds_parts: Vec<&str> = parts[2].split('.').collect();
let seconds: u32 = seconds_parts[0]
.parse()
.map_err(|_| CoreError::InvalidTime(format!("Invalid seconds: {}", seconds_parts[0])))?;
let centiseconds = if seconds_parts.len() > 1 {
let frac_str = seconds_parts[1];
if frac_str.is_empty() || !frac_str.bytes().all(|b| b.is_ascii_digit()) {
return Err(CoreError::InvalidTime(format!(
"Invalid centiseconds: {frac_str}"
)));
}
frac_str
.parse::<u32>()
.map_err(|_| CoreError::InvalidTime(format!("Invalid centiseconds: {frac_str}")))?
} else {
0
};
if minutes >= 60 {
return Err(CoreError::InvalidTime(format!(
"Minutes must be < 60: {minutes}"
)));
}
if seconds >= 60 {
return Err(CoreError::InvalidTime(format!(
"Seconds must be < 60: {seconds}"
)));
}
Ok(hours * 360_000 + minutes * 6_000 + seconds * 100 + centiseconds)
}
#[must_use]
pub fn format_ass_time(centiseconds: u32) -> String {
let hours = centiseconds / 360_000;
let remainder = centiseconds % 360_000;
let minutes = remainder / 6000;
let remainder = remainder % 6000;
let seconds = remainder / 100;
let cs = remainder % 100;
format!("{hours}:{minutes:02}:{seconds:02}.{cs:02}")
}