Files
asciinema/src/asciicast/util.rs
2025-10-17 16:39:09 +02:00

42 lines
1.1 KiB
Rust

use std::time::Duration;
use anyhow::Result;
use serde::{Deserialize, Deserializer};
pub fn deserialize_time<'de, D>(deserializer: D) -> Result<Duration, D::Error>
where
D: Deserializer<'de>,
{
use serde::de::Error;
let value: serde_json::Value = Deserialize::deserialize(deserializer)?;
let number = value
.as_f64()
.map(|v| v.to_string())
.ok_or(Error::custom("expected number"))?;
let parts: Vec<&str> = number.split('.').collect();
match parts.as_slice() {
[left, right] => {
let secs: u64 = left.parse().map_err(Error::custom)?;
let right = right.trim();
let micros: u64 = format!("{:0<6}", &right[..(6.min(right.len()))])
.parse()
.map_err(Error::custom)?;
Ok(Duration::from_micros(secs * 1_000_000 + micros))
}
[number] => {
let secs: u64 = number.parse().map_err(Error::custom)?;
Ok(Duration::from_micros(secs * 1_000_000))
}
_ => Err(Error::custom(format!("invalid time format: {value}"))),
}
}