limitless-exchange-rust-sdk 1.0.13

Rust SDK for Limitless Exchange CLOB and NegRisk trading
Documentation
pub(crate) fn chrono_timestamp() -> String {
    use std::time::{SystemTime, UNIX_EPOCH};

    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap_or_default();
    let secs = now.as_secs();
    let millis = now.subsec_millis();

    let datetime = chrono_like::DateTime::from_unix(secs as i64);
    format!(
        "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:03}Z",
        datetime.year,
        datetime.month,
        datetime.day,
        datetime.hour,
        datetime.minute,
        datetime.second,
        millis
    )
}

mod chrono_like {
    pub struct DateTime {
        pub year: i32,
        pub month: u32,
        pub day: u32,
        pub hour: u32,
        pub minute: u32,
        pub second: u32,
    }

    impl DateTime {
        pub fn from_unix(timestamp: i64) -> Self {
            let secs_per_day = 86_400;
            let days = timestamp.div_euclid(secs_per_day);
            let secs_of_day = timestamp.rem_euclid(secs_per_day);

            let (year, month, day) = civil_from_days(days);
            Self {
                year,
                month,
                day,
                hour: (secs_of_day / 3600) as u32,
                minute: ((secs_of_day % 3600) / 60) as u32,
                second: (secs_of_day % 60) as u32,
            }
        }
    }

    fn civil_from_days(days: i64) -> (i32, u32, u32) {
        let z = days + 719_468;
        let era = if z >= 0 { z } else { z - 146_096 } / 146_097;
        let doe = z - era * 146_097;
        let yoe = (doe - doe / 1_460 + doe / 36_524 - doe / 146_096) / 365;
        let y = yoe + era * 400;
        let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
        let mp = (5 * doy + 2) / 153;
        let d = doy - (153 * mp + 2) / 5 + 1;
        let m = mp + if mp < 10 { 3 } else { -9 };
        let year = y + if m <= 2 { 1 } else { 0 };
        (year as i32, m as u32, d as u32)
    }
}

#[cfg(test)]
mod tests {
    use super::chrono_like::DateTime;
    use super::chrono_timestamp;

    #[test]
    fn date_time_handles_leap_day() {
        let value = DateTime::from_unix(1_709_164_800);
        assert_eq!(value.year, 2024);
        assert_eq!(value.month, 2);
        assert_eq!(value.day, 29);
    }

    #[test]
    fn date_time_handles_century_boundary() {
        let value = DateTime::from_unix(4_102_444_800);
        assert_eq!(value.year, 2100);
        assert_eq!(value.month, 1);
        assert_eq!(value.day, 1);
    }

    #[test]
    fn timestamp_is_iso_8601_utc_like() {
        let value = chrono_timestamp();
        assert!(value.ends_with('Z'));
        assert_eq!(value.len(), 24);
        assert_eq!(&value[4..5], "-");
        assert_eq!(&value[7..8], "-");
        assert_eq!(&value[10..11], "T");
    }
}