mod header;
mod parts;
mod read;
mod write;
#[cfg(feature = "alloc")]
mod owned;
#[cfg(not(feature = "alloc"))]
mod array_vec;
#[cfg(test)]
pub(crate) mod test_util;
pub(crate) use self::{
header::{
BinaryHeader, BorrowedBinary, BorrowedText, EnumHeader, MapHeader, MapKeyHeader,
MapValueHeader, RecordHeader, RecordTupleHeader, RecordTupleValueHeader, RecordValueHeader,
SeqHeader, SeqValueHeader, TagHintPart, TagPart, TaggedHeader, TextHeader, TupleHeader,
TupleValueHeader,
},
parts::{into_value_parts, Parts, RawStorage, RawStorageMut, ValueBufParts, ValueParts},
read::stream_parts,
write::Encode,
};
#[cfg(feature = "alloc")]
pub(crate) use self::owned::make_owned;
#[cfg(not(feature = "alloc"))]
pub(crate) use self::array_vec::ArrayVec;
use crate::Error;
use zerocopy::{try_transmute, Immutable, KnownLayout, TryFromBytes};
const KIND_MASK: u8 = 0b0001_1111;
#[cfg(feature = "alloc")]
const TAG_OWNED: u8 = 0b1000_0000;
const TAG_BORROWED: u8 = 0b0100_0000;
const PARTS_CAP: usize = 256;
pub(crate) const MAX_PARTS_LEN: usize = (u32::MAX - 8) as usize;
#[derive(Clone, Copy, PartialEq, Eq, TryFromBytes, Immutable, KnownLayout)]
#[repr(u8)]
enum Kind {
Null = 0,
Bool = 1,
U8 = 2,
U16 = 3,
U32 = 4,
U64 = 5,
U128 = 6,
I8 = 7,
I16 = 8,
I32 = 9,
I64 = 10,
I128 = 11,
F32 = 12,
F64 = 13,
Tag = 14,
TagHint = 15,
Text = 16,
Binary = 17,
MapKey = 18,
MapValue = 19,
SeqValue = 20,
Enum = 21,
Tagged = 22,
RecordValue = 23,
TupleValue = 24,
RecordTupleValue = 25,
Map = 26,
Seq = 27,
Record = 28,
Tuple = 29,
RecordTuple = 30,
}
impl Kind {
#[inline]
fn from_tag_byte(b: u8) -> Kind {
try_transmute!(b & KIND_MASK).expect("tag byte holds an invalid kind")
}
#[inline]
fn to_tag_byte(&self, owned: bool, borrowed: bool) -> Result<u8, Error> {
let mut tag = *self as u8;
debug_assert!(tag <= KIND_MASK);
#[cfg(feature = "alloc")]
{
if owned {
tag |= TAG_OWNED;
}
}
#[cfg(not(feature = "alloc"))]
{
if owned {
return Err(Error::no_alloc("owned value part"));
}
}
if borrowed {
tag |= TAG_BORROWED;
}
Ok(tag)
}
#[inline]
const fn is_container(&self) -> bool {
let tag = *self as u8;
tag >= 16
}
#[inline]
const fn is_entry_tracking(&self) -> bool {
let tag = *self as u8;
tag >= 26
}
}