use crate::{Prefixes, Doc};
pub struct Gener {
buf: Vec<u8>
}
impl Gener {
pub const fn new()-> Self { Self { buf: Vec::new() } }
pub fn with_capacity(size_hint: usize)-> Self { Self { buf: Vec::with_capacity(size_hint) } }
pub fn run(mut self, doc: &Doc)-> Vec<u8> {
self.gener(doc);
self.buf
}
fn gener(&mut self, doc: &Doc) {
match doc {
Doc::Nul=> self.buf.push(Prefixes::NUL),
Doc::Number(s)=> {
self.buf.push(Prefixes::NUMBER);
self.buf(s.as_bytes());
}
Doc::Bool(b)=> self.buf.push(if *b { Prefixes::TRUE } else { Prefixes::FALSE }),
Doc::Buffer(b)=> {
self.buf.push(Prefixes::BUFFER);
self.buf(b)
},
Doc::String(s)=> {
self.buf.push(Prefixes::STRING);
self.buf(s.as_bytes())
}
Doc::Array(a)=> {
self.buf.push(Prefixes::ARRAY);
self.vint(a.len());
for item in a {
self.gener(item);
}
}
Doc::Object(o)=> {
self.buf.push(Prefixes::OBJECT);
self.vint(o.len());
for item in o {
self.buf(item.0.as_bytes());
self.gener(&item.1);
}
}
};
}
fn buf(&mut self, b: &[u8]) {
self.buf.push(b.len() as u8);
self.buf.extend_from_slice(b);
}
fn vint(&mut self, mut n: usize) {
let mut bytes = [0u8; 4];
let mut i = 1;
bytes[0] = (n & 0x3F) as u8;
n >>= 6;
while n > 0 {
bytes[i] = (n & 0xFF) as u8;
i += 1;
n >>= 8;
}
bytes[0] |= ((i - 1) << 6) as u8;
self.buf.extend_from_slice(bytes.get(0..).expect("Unexpect KeyBinDoc VINT over 2**30 - 1"));
}
}