libsurfer/cxxrtl/
timestamp.rs

1use std::str::FromStr;
2
3use eyre::{Context, Result};
4use num::{BigUint, Zero};
5use serde::{Deserialize, Deserializer, Serialize};
6
7#[derive(Debug, Clone)]
8pub struct CxxrtlTimestamp {
9    seconds: BigUint,
10    femtoseconds: BigUint,
11}
12
13impl CxxrtlTimestamp {
14    pub fn zero() -> Self {
15        Self {
16            seconds: BigUint::zero(),
17            femtoseconds: BigUint::zero(),
18        }
19    }
20
21    fn from_str(s: &str) -> Result<Self> {
22        let split = s.split('.').collect::<Vec<_>>();
23
24        Ok(CxxrtlTimestamp {
25            seconds: BigUint::from_str(split[0])
26                .with_context(|| format!("When parsing seconds from {s}"))?,
27            femtoseconds: BigUint::from_str(split[1])
28                .with_context(|| format!("When parsing femtoseconds from {s}"))?,
29        })
30    }
31
32    pub fn from_femtoseconds(femto: BigUint) -> Self {
33        Self {
34            seconds: &femto / BigUint::from(1_000_000_000_000_000u64),
35            femtoseconds: &femto % BigUint::from(1_000_000_000_000_000u64),
36        }
37    }
38
39    pub fn as_femtoseconds(&self) -> BigUint {
40        &self.seconds * BigUint::from(1_000_000_000_000_000u64) + &self.femtoseconds
41    }
42}
43
44impl<'de> Deserialize<'de> for CxxrtlTimestamp {
45    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
46    where
47        D: Deserializer<'de>,
48    {
49        let buf = String::deserialize(deserializer)?;
50
51        Self::from_str(&buf).map_err(serde::de::Error::custom)
52    }
53}
54
55impl Serialize for CxxrtlTimestamp {
56    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
57    where
58        S: serde::Serializer,
59    {
60        self.to_string().serialize(serializer)
61    }
62}
63
64impl std::fmt::Display for CxxrtlTimestamp {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        write!(f, "{}.{:015}", self.seconds, self.femtoseconds)
67    }
68}