use core::fmt;
use crate::{Context, Writer};
pub(crate) const NULL: u8 = 0;
pub(crate) const TRUE: u8 = 1;
pub(crate) const FALSE: u8 = 2;
pub(crate) const INT: u8 = 3;
pub(crate) const INT5: u8 = 4;
pub(crate) const FLOAT: u8 = 5;
pub(crate) const FLOAT5: u8 = 6;
pub(crate) const TEXT: u8 = 7;
pub(crate) const TEXTJ: u8 = 8;
pub(crate) const TEXT5: u8 = 9;
pub(crate) const TEXTRAW: u8 = 10;
pub(crate) const ARRAY: u8 = 11;
pub(crate) const OBJECT: u8 = 12;
#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) struct Kind(pub(crate) u8);
impl fmt::Display for Kind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = match self.0 {
NULL => "NULL",
TRUE => "TRUE",
FALSE => "FALSE",
INT => "INT",
INT5 => "INT5",
FLOAT => "FLOAT",
FLOAT5 => "FLOAT5",
TEXT => "TEXT",
TEXTJ => "TEXTJ",
TEXT5 => "TEXT5",
TEXTRAW => "TEXTRAW",
ARRAY => "ARRAY",
OBJECT => "OBJECT",
other => return write!(f, "RESERVED({other})"),
};
f.write_str(name)
}
}
impl fmt::Debug for Kind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
#[inline]
pub(crate) const fn is_text(kind: u8) -> bool {
matches!(kind, TEXT | TEXTJ | TEXT5 | TEXTRAW)
}
#[inline]
pub(crate) const fn is_int(kind: u8) -> bool {
matches!(kind, INT | INT5)
}
#[inline]
pub(crate) const fn is_float(kind: u8) -> bool {
matches!(kind, FLOAT | FLOAT5)
}
#[inline]
pub(crate) fn write_header<W, C>(
cx: C,
writer: &mut W,
kind: u8,
len: usize,
) -> Result<(), C::Error>
where
W: ?Sized + Writer,
C: Context,
{
debug_assert!(kind <= OBJECT, "Element type out of range");
if len <= 11 {
return writer.write_byte(cx, ((len as u8) << 4) | kind);
}
if let Ok(len) = u8::try_from(len) {
writer.write_byte(cx, 0xc0 | kind)?;
return writer.write_byte(cx, len);
}
if let Ok(len) = u16::try_from(len) {
writer.write_byte(cx, 0xd0 | kind)?;
return writer.write_bytes(cx, &len.to_be_bytes());
}
if let Ok(len) = u32::try_from(len) {
writer.write_byte(cx, 0xe0 | kind)?;
return writer.write_bytes(cx, &len.to_be_bytes());
}
writer.write_byte(cx, 0xf0 | kind)?;
writer.write_bytes(cx, &(len as u64).to_be_bytes())
}