use std::{
io::Cursor,
time::{Duration, SystemTime, UNIX_EPOCH},
};
use bincode::Options;
use serde::de::DeserializeOwned;
use uuid7::Uuid;
pub trait ToTime {
fn to_system_time(&self) -> SystemTime;
fn to_ts(&self) -> u64;
}
impl ToTime for Uuid {
#[inline]
fn to_system_time(&self) -> SystemTime {
UNIX_EPOCH + Duration::from_millis(self.to_ts())
}
#[inline]
fn to_ts(&self) -> u64 {
let mut bytes = [0; 8];
bytes[2..].copy_from_slice(&self.as_bytes()[..6]);
u64::from_be_bytes(bytes)
}
}
mod bincode_option_mod {
use bincode::{DefaultOptions, Options};
pub type BincodeOptions = impl Options + Copy;
#[inline]
pub fn bincode_option() -> BincodeOptions {
DefaultOptions::new()
.with_fixint_encoding()
.with_little_endian()
.with_limit(1 << 12)
}
}
pub use bincode_option_mod::{bincode_option, BincodeOptions};
pub fn try_decode<T: DeserializeOwned>(data: &[u8]) -> Result<Option<(T, u64)>, bincode::Error> {
if data.is_empty() {
return Ok(None);
}
let mut cur = Cursor::new(data);
let res = bincode_option().deserialize_from(&mut cur);
match res {
Ok(val) => Ok(Some((val, cur.position() as _))),
Err(e) => match *e {
bincode::ErrorKind::Io(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => Ok(None),
_ => Err(e),
},
}
}
pub trait SubArray {
const LEN: usize;
type T;
fn sub<const L: usize, const R: usize>(&self) -> &[Self::T; R - L]
where
Bool<{ Self::LEN >= R }>: True,
Bool<{ R >= L }>: True;
}
pub trait SubArrayMut: SubArray {
fn sub_mut<const L: usize, const R: usize>(&mut self) -> &mut [Self::T; R - L]
where
Bool<{ Self::LEN >= R }>: True,
Bool<{ R >= L }>: True;
}
impl<T, const LEN: usize> SubArray for [T; LEN] {
type T = T;
const LEN: usize = LEN;
fn sub<const L: usize, const R: usize>(&self) -> &[T; R - L]
where
Bool<{ Self::LEN >= R }>: True,
Bool<{ R >= L }>: True,
{
self[L..R].try_into().unwrap()
}
}
impl<T, const LEN: usize> SubArrayMut for [T; LEN] {
fn sub_mut<const L: usize, const R: usize>(&mut self) -> &mut [T; R - L]
where
Bool<{ Self::LEN >= R }>: True,
Bool<{ R >= L }>: True,
{
(&mut self[L..R]).try_into().unwrap()
}
}
pub trait True {}
pub struct Bool<const B: bool>;
impl True for Bool<true> {}
#[test]
fn test_subarray() {
let a = [1, 2, 3, 4, 5];
assert_eq!(a.sub::<0, 5>(), &a);
assert_eq!(a.sub::<1, 3>(), &[2, 3]);
}
pub trait Discard: Sized {
fn drop(self) {}
}
impl<T> Discard for T {}