use crate::error::{Error, Result};
pub const TYPE_NULL_BOOL: u8 = 0;
pub const TYPE_NUMBER: u8 = 1;
pub const TYPE_STRING: u8 = 2;
pub const TYPE_OBJECT: u8 = 3;
pub const TYPE_TYPED_ARRAY: u8 = 4;
pub const TYPE_GENERIC_ARRAY: u8 = 5;
pub const TYPE_EXTENSION: u8 = 6;
pub const NUM_FLOAT: u8 = 0;
pub const NUM_SIGNED: u8 = 1;
pub const NUM_UNSIGNED: u8 = 2;
pub const KEY_STRING: u8 = 0;
pub const KEY_SIGNED: u8 = 1;
pub const KEY_UNSIGNED: u8 = 2;
pub const ARRAY_FLOAT: u8 = 0;
pub const ARRAY_SIGNED: u8 = 1;
pub const ARRAY_UNSIGNED: u8 = 2;
pub const ARRAY_BOOL_OR_STRING: u8 = 3;
pub const EXT_DELIMITER: u8 = 0;
pub const EXT_TYPE_TAG: u8 = 1;
pub const EXT_MATRICES: u8 = 2;
pub const EXT_COMPLEX: u8 = 3;
#[inline]
pub fn complex_component_bytes(class: u8, byte_code: u8) -> Option<usize> {
match class {
NUM_FLOAT => match byte_code {
0 | 1 => Some(2),
2 => Some(4),
3 => Some(8),
_ => None,
},
NUM_SIGNED | NUM_UNSIGNED => match byte_code {
0..=4 => Some(1usize << byte_code),
_ => None,
},
_ => None,
}
}
#[inline]
pub fn make_header(ty: u8, subtype: u8, byte_count_code: u8) -> u8 {
(byte_count_code << 5) | ((subtype & 0b11) << 3) | (ty & 0b111)
}
#[inline]
pub const fn make_extension_header(ext_id: u8) -> u8 {
((ext_id & 0x1f) << 3) | TYPE_EXTENSION
}
#[inline]
pub fn parse_type(header: u8) -> u8 {
header & 0b111
}
#[inline]
pub fn parse_subtype(header: u8) -> u8 {
(header >> 3) & 0b11
}
#[inline]
pub fn parse_byte_count_code(header: u8) -> u8 {
header >> 5
}
#[inline]
pub fn parse_extension_id(header: u8) -> u8 {
header >> 3
}
#[inline]
pub fn is_bool(header: u8) -> bool {
(header & 0b111) == TYPE_NULL_BOOL && (header & 0b1000) != 0
}
#[inline]
pub fn bool_value(header: u8) -> Result<bool> {
if !is_bool(header) {
return Err(Error::InvalidType("not a boolean header"));
}
Ok((header & 0b10000) != 0)
}