motorcortex-rust 0.5.0

Motorcortex Rust: a Rust client for the Motorcortex Core real-time control system (async + blocking).
Documentation
//! Wire-level timestamp embedded in subscription payloads.
//!
//! 16 bytes, two little-endian `i64`s (seconds + nanoseconds). The
//! on-wire layout is fixed by the server; decoding is explicit
//! rather than a native-layout pointer read so the library stays
//! portable to big-endian hosts.

use chrono::{DateTime, Local, Utc};

/// Size of the wire representation: two `i64` fields packed
/// back-to-back.
pub(crate) const TIMESPEC_WIRE_SIZE: usize = 16;

#[derive(Debug, Clone, Copy)]
pub struct TimeSpec {
    pub sec: i64,  // Seconds
    pub nsec: i64, // Nanoseconds
}

impl TimeSpec {
    /// Decode a [`TimeSpec`] from the first 16 bytes of `buffer`.
    /// Returns `None` if the buffer is shorter than that.
    pub fn from_buffer(buffer: &[u8]) -> Option<Self> {
        if buffer.len() < TIMESPEC_WIRE_SIZE {
            return None;
        }
        // Explicit little-endian decode of each field. Fixed-size
        // array slicing gives us `TryFrom` for the two 8-byte
        // chunks; `i64::from_le_bytes` is endian-safe and matches
        // what the server writes.
        let sec = i64::from_le_bytes(buffer[0..8].try_into().ok()?);
        let nsec = i64::from_le_bytes(buffer[8..16].try_into().ok()?);
        Some(Self { sec, nsec })
    }

    pub fn to_date_time(&self) -> DateTime<Local> {
        self.to_utc_date_time().with_timezone(&Local)
    }

    pub fn to_utc_date_time(&self) -> DateTime<Utc> {
        DateTime::from_timestamp(self.sec, self.nsec as u32).expect("Invalid TimeSpec")
    }
}