mod decoder;
pub(crate) mod interner;
#[cfg(test)]
mod tests;
pub(crate) mod writer;
use std::fmt;
use bumpalo::Bump;
pub use decoder::Decoder;
pub use writer::Writer;
use crate::borrowed::ValueRef;
use crate::value::Value;
pub const MAGIC: &[u8; 4] = b"YOGD";
pub const VERSION: u8 = 2;
pub const MAX_DEPTH: usize = 256;
pub mod tag {
macro_rules! tags {
($($(#[$doc:meta])* $name:ident = $value:expr;)*) => {
$($(#[$doc])* pub const $name: u8 = $value;)*
pub const ALL: &[(&str, u8)] = &[$((stringify!($name), $value)),*];
};
}
tags! {
NULL = 0;
FALSE = 1;
TRUE = 2;
INT = 3;
FLOAT = 4;
STR = 5;
LIST = 6;
MAP = 7;
REF = 8;
TAG = 9;
RES = 10;
TEXT = 11;
IMAGE = 12;
COLOR = 13;
LANG = 14;
BYTES = 15;
INTS = 16;
STREAM = 17;
FLOAT32 = 18;
FLOATS = 19;
FLOATS32 = 20;
}
}
pub(crate) const STREAM_LEN_BYTES: usize = 4;
pub(crate) const NEW_STRING: u64 = 1;
pub(crate) const VARINT_BITS: u64 = 0x7F;
pub(crate) const VARINT_MORE: u8 = 0x80;
pub(crate) const VARINT_SHIFT: u32 = 7;
pub(crate) fn varint(out: &mut Vec<u8>, mut n: u64) {
while n > VARINT_BITS {
out.push((n as u8) | VARINT_MORE);
n >>= VARINT_SHIFT;
}
out.push(n as u8);
}
pub(crate) const VARINT_MAX_SHIFT: u32 = 64;
pub(crate) fn read_varint(b: &[u8], i: &mut usize) -> Option<u64> {
let mut n = 0u64;
let mut shift = 0;
while shift < VARINT_MAX_SHIFT {
let byte = *b.get(*i)?;
*i += 1;
n |= (u64::from(byte) & VARINT_BITS) << shift;
if byte & VARINT_MORE == 0 {
return Some(n);
}
shift += VARINT_SHIFT;
}
None
}
pub(crate) fn zigzag(n: i64) -> u64 {
((n << 1) ^ (n >> 63)) as u64
}
pub(crate) fn unzigzag(z: u64) -> i64 {
((z >> 1) as i64) ^ -((z & 1) as i64)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DecodeError {
pub message: String,
pub offset: usize,
}
impl fmt::Display for DecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "byte {}: {}", self.offset, self.message)
}
}
impl std::error::Error for DecodeError {}
pub fn encode(value: &Value) -> Vec<u8> {
let mut w = Writer::new();
w.value(value);
w.finish()
}
pub fn decode(bytes: &[u8]) -> Result<Value, DecodeError> {
let mut d = Decoder::open(bytes)?;
let v = d.value()?;
d.end()?;
Ok(v)
}
pub fn decode_ref<'a>(bytes: &'a [u8], arena: &'a Bump) -> Result<ValueRef<'a>, DecodeError> {
let mut d = Decoder::open(bytes)?;
let v = d.value_ref(arena)?;
d.end()?;
Ok(v)
}