mirror of
https://github.com/TxtDot/dalet-rs.git
synced 2025-03-13 19:24:38 +03:00
This commit is contained in:
parent
5eb9e2abb6
commit
2737a066f5
14 changed files with 1202 additions and 21 deletions
110
src/daletpack/encode.rs
Normal file
110
src/daletpack/encode.rs
Normal file
|
@ -0,0 +1,110 @@
|
|||
use crate::daletl::{Argument, Body, IsNull, Tag, Tid};
|
||||
|
||||
use super::{DaletPackError, TypeId};
|
||||
|
||||
pub fn encode(root: &Vec<Tag>) -> Result<Vec<u8>, DaletPackError> {
|
||||
Ok(zstd::bulk::compress(&encode_no_compress(root)?, 5)
|
||||
.map_err(|_| DaletPackError::ZstdCompressError)?)
|
||||
}
|
||||
|
||||
pub fn encode_no_compress(root: &Vec<Tag>) -> Result<Vec<u8>, DaletPackError> {
|
||||
if root.len() > 2usize.pow(32) {
|
||||
return Err(DaletPackError::RootMaxSizeExceeded);
|
||||
}
|
||||
|
||||
let mut bv: Vec<u8> = Vec::new();
|
||||
|
||||
for tag in root {
|
||||
write_tag(&mut bv, tag)?;
|
||||
}
|
||||
|
||||
Ok(bv)
|
||||
}
|
||||
|
||||
fn write_int(bv: &mut Vec<u8>, n: u8) {
|
||||
bv.push(1);
|
||||
bv.push(n);
|
||||
}
|
||||
|
||||
fn write_str(bv: &mut Vec<u8>, string: &String) -> Result<(), DaletPackError> {
|
||||
let size = string.len();
|
||||
|
||||
if size > 2usize.pow(32) {
|
||||
return Err(DaletPackError::StrMaxSizeExceeded);
|
||||
}
|
||||
|
||||
if size <= 256 {
|
||||
bv.push(TypeId::Str8 as u8);
|
||||
bv.push((size - 1) as u8);
|
||||
} else if size <= 65536 {
|
||||
bv.push(TypeId::Str16 as u8);
|
||||
bv.extend(((size - 1) as u16).to_be_bytes());
|
||||
} else {
|
||||
bv.push(TypeId::Str32 as u8);
|
||||
bv.extend(((size - 1) as u32).to_be_bytes());
|
||||
}
|
||||
|
||||
bv.extend_from_slice(string.as_bytes());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_array(bv: &mut Vec<u8>, arr: &Vec<Tag>) -> Result<(), DaletPackError> {
|
||||
if arr.len() > 2usize.pow(32) {
|
||||
return Err(DaletPackError::ArrMaxSizeExceeded);
|
||||
}
|
||||
|
||||
bv.push(TypeId::TagArray as u8);
|
||||
|
||||
for tag in arr {
|
||||
write_tag(bv, tag)?;
|
||||
}
|
||||
|
||||
bv.push(TypeId::TagArrayEnd as u8);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_tag(bv: &mut Vec<u8>, tag: &Tag) -> Result<(), DaletPackError> {
|
||||
if tag.id == Tid::El {
|
||||
write_tag_body(bv, &tag.body)?;
|
||||
} else if tag.body.is_null() && tag.argument.is_null() {
|
||||
bv.push(TypeId::TagId as u8);
|
||||
bv.push(tag.id as u8);
|
||||
} else if tag.argument.is_null() {
|
||||
bv.push(TypeId::TagIdBody as u8);
|
||||
bv.push(tag.id as u8);
|
||||
write_tag_body(bv, &tag.body)?;
|
||||
} else if tag.body.is_null() {
|
||||
bv.push(TypeId::TagIdArgument as u8);
|
||||
bv.push(tag.id as u8);
|
||||
write_tag_argument(bv, &tag.argument)?;
|
||||
} else {
|
||||
bv.push(TypeId::TagIdBodyArgument as u8);
|
||||
bv.push(tag.id as u8);
|
||||
write_tag_body(bv, &tag.body)?;
|
||||
write_tag_argument(bv, &tag.argument)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_tag_body(bv: &mut Vec<u8>, body: &Body) -> Result<(), DaletPackError> {
|
||||
match body {
|
||||
Body::Text(s) => write_str(bv, s)?,
|
||||
Body::Tags(tags) => write_array(bv, tags)?,
|
||||
Body::Null => Err(DaletPackError::WriteNullBody)?,
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_tag_argument(bv: &mut Vec<u8>, argument: &Argument) -> Result<(), DaletPackError> {
|
||||
match argument {
|
||||
Argument::Text(s) => write_str(bv, s)?,
|
||||
Argument::Number(n) => write_int(bv, *n),
|
||||
Argument::Null => Err(DaletPackError::WriteNullArgument)?,
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
6
src/daletpack/mod.rs
Normal file
6
src/daletpack/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
mod encode;
|
||||
mod types;
|
||||
|
||||
pub mod utils;
|
||||
pub use encode::*;
|
||||
pub use types::*;
|
27
src/daletpack/types.rs
Normal file
27
src/daletpack/types.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
use num_enum::TryFromPrimitive;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum DaletPackError {
|
||||
StrMaxSizeExceeded,
|
||||
ArrMaxSizeExceeded,
|
||||
RootMaxSizeExceeded,
|
||||
ZstdCompressError,
|
||||
|
||||
WriteNullBody,
|
||||
WriteNullArgument,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, TryFromPrimitive, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum TypeId {
|
||||
Int8 = 1,
|
||||
Str8 = 4,
|
||||
Str16,
|
||||
Str32,
|
||||
TagArray,
|
||||
TagArrayEnd,
|
||||
TagId = 12,
|
||||
TagIdBody,
|
||||
TagIdArgument,
|
||||
TagIdBodyArgument,
|
||||
}
|
3
src/daletpack/utils.rs
Normal file
3
src/daletpack/utils.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub fn compress_zstd(data: &Vec<u8>) -> std::io::Result<Vec<u8>> {
|
||||
zstd::bulk::compress(data, 22)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue