use std::io::{self, Read, Write};
pub(crate) const MAGIC: &[u8; 8] = b"KEVYSNAP";
pub(crate) const VERSION: u8 = 4;
pub(crate) const VERSION_FEED_CURSOR: u8 = 5;
pub(crate) const VERSION_HASH_TTL: u8 = 6;
pub(crate) const VERSION_RELATIVE_TTL: u8 = 2;
pub(crate) const VERSION_ABSOLUTE_TTL: u8 = 3;
pub(crate) const OP_EOF: u8 = 0;
pub(crate) const OP_STR: u8 = 1;
pub(crate) const OP_HASH: u8 = 2;
pub(crate) const OP_LIST: u8 = 3;
pub(crate) const OP_SET: u8 = 4;
pub(crate) const OP_ZSET: u8 = 5;
pub(crate) const OP_STREAM: u8 = 6;
pub(crate) const OP_HFTTL: u8 = 7;
pub(crate) const SNAPSHOT_BUF_CAP: usize = 1 << 20;
pub(crate) fn write_ttl<W: Write>(w: &mut W, ttl: Option<u64>) -> io::Result<()> {
match ttl {
Some(ms) => {
w.write_all(&[1u8])?;
w.write_all(&ms.to_le_bytes())?;
}
None => w.write_all(&[0u8])?,
}
Ok(())
}
pub(crate) fn read_ttl<R: Read>(r: &mut R) -> io::Result<Option<u64>> {
if read_u8(r)? == 1 {
Ok(Some(read_u64(r)?))
} else {
Ok(None)
}
}
pub(crate) fn write_bytes<W: Write>(w: &mut W, b: &[u8]) -> io::Result<()> {
w.write_all(&(b.len() as u32).to_le_bytes())?;
w.write_all(b)
}
pub(crate) fn read_bytes<R: Read>(r: &mut R) -> io::Result<Vec<u8>> {
let len = read_u32(r)? as usize;
let mut buf = vec![0u8; len];
r.read_exact(&mut buf)?;
Ok(buf)
}
pub(crate) fn read_u8<R: Read>(r: &mut R) -> io::Result<u8> {
let mut b = [0u8; 1];
r.read_exact(&mut b)?;
Ok(b[0])
}
pub(crate) fn read_u32<R: Read>(r: &mut R) -> io::Result<u32> {
let mut b = [0u8; 4];
r.read_exact(&mut b)?;
Ok(u32::from_le_bytes(b))
}
pub(crate) fn read_u64<R: Read>(r: &mut R) -> io::Result<u64> {
let mut b = [0u8; 8];
r.read_exact(&mut b)?;
Ok(u64::from_le_bytes(b))
}