use std::io::Read;
use std::net::TcpStream;
pub const ASYNC: u8 = 0;
pub const SYNC: u8 = 1;
pub const RESPONSE: u8 = 2;
pub fn sym_atom(s: &str) -> Vec<u8> {
let mut b = vec![(-11i8) as u8];
b.extend_from_slice(s.as_bytes());
b.push(0);
b
}
pub fn long_atom(v: i64) -> Vec<u8> {
let mut b = vec![(-7i8) as u8];
b.extend_from_slice(&v.to_le_bytes());
b
}
pub fn sym_vec(syms: &[&str]) -> Vec<u8> {
let mut b = vec![11u8, 0u8];
b.extend_from_slice(&(syms.len() as i32).to_le_bytes());
for s in syms {
b.extend_from_slice(s.as_bytes());
b.push(0);
}
b
}
pub fn long_vec(vals: &[i64]) -> Vec<u8> {
let mut b = vec![7u8, 0u8];
b.extend_from_slice(&(vals.len() as i32).to_le_bytes());
for v in vals {
b.extend_from_slice(&v.to_le_bytes());
}
b
}
pub fn char_vec(s: &str) -> Vec<u8> {
let mut b = vec![10u8, 0u8];
b.extend_from_slice(&(s.len() as i32).to_le_bytes());
b.extend_from_slice(s.as_bytes());
b
}
pub fn list(items: &[Vec<u8>]) -> Vec<u8> {
let mut b = vec![0u8, 0u8];
b.extend_from_slice(&(items.len() as i32).to_le_bytes());
for it in items {
b.extend_from_slice(it);
}
b
}
pub fn dict(keys: Vec<u8>, vals: Vec<u8>) -> Vec<u8> {
let mut b = vec![99u8];
b.extend(keys);
b.extend(vals);
b
}
pub fn frame(msgtype: u8, body: &[u8]) -> Vec<u8> {
let size = (8 + body.len()) as u32;
let mut b = vec![1u8, msgtype, 0u8, 0u8]; b.extend_from_slice(&size.to_le_bytes());
b.extend_from_slice(body);
b
}
pub fn read_frame(sock: &mut TcpStream) -> Option<(u8, Vec<u8>)> {
let mut hdr = [0u8; 8];
sock.read_exact(&mut hdr).ok()?;
let size = u32::from_le_bytes([hdr[4], hdr[5], hdr[6], hdr[7]]) as usize;
let mut body = vec![0u8; size.saturating_sub(8)];
sock.read_exact(&mut body).ok()?;
Some((hdr[1], body))
}
pub fn drain_one(sock: &mut TcpStream) -> bool {
read_frame(sock).is_some()
}