use alloc::string::String;
use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Timestamp(pub i64);
impl Timestamp {
#[inline]
pub const fn from_secs(secs: i64) -> Self {
Self(secs)
}
#[inline]
pub const fn as_secs(self) -> i64 {
self.0
}
}
impl fmt::Display for Timestamp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}s (unix)", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum MarkerStyle {
Append,
UserEvent,
Waveform,
GlobalEvent,
Unknown(String),
}
impl MarkerStyle {
pub fn from_code(code: &str) -> Self {
match code.trim_end_matches('\0') {
"apnd" => Self::Append,
s if s.starts_with("usr") => Self::UserEvent,
"wave" => Self::Waveform,
"glbl" => Self::GlobalEvent,
other => Self::Unknown(other.into()),
}
}
}
impl fmt::Display for MarkerStyle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Append => write!(f, "Append"),
Self::UserEvent => write!(f, "UserEvent"),
Self::Waveform => write!(f, "Waveform"),
Self::GlobalEvent => write!(f, "GlobalEvent"),
Self::Unknown(s) => write!(f, "Unknown({s})"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Marker {
pub label: String,
pub global_sample_index: usize,
pub channel: Option<usize>,
pub style: MarkerStyle,
pub created_at: Option<Timestamp>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn marker_style_apnd() {
assert_eq!(MarkerStyle::from_code("apnd"), MarkerStyle::Append);
}
#[test]
fn marker_style_user_events() {
assert_eq!(MarkerStyle::from_code("usr1"), MarkerStyle::UserEvent);
assert_eq!(MarkerStyle::from_code("usr8"), MarkerStyle::UserEvent);
}
#[test]
fn marker_style_unknown() {
let s = MarkerStyle::from_code("xyzw");
assert!(matches!(s, MarkerStyle::Unknown(_)));
}
#[test]
fn marker_style_unknown_with_null_padding() {
let s = MarkerStyle::from_code("apnd\0");
assert_eq!(s, MarkerStyle::Append);
}
#[test]
fn timestamp_round_trip() {
let ts = Timestamp::from_secs(1_700_000_000);
assert_eq!(ts.as_secs(), 1_700_000_000);
}
}