Reworked interface and data handling.

This commit is contained in:
yukirij 2023-05-02 21:43:38 -07:00
parent 9b3f7698b5
commit 4a7700b6ee
22 changed files with 967 additions and 206 deletions

8
Cargo.lock generated
View File

@ -5,3 +5,11 @@ version = 3
[[package]]
name = "szun"
version = "0.1.0"
dependencies = [
"util",
]
[[package]]
name = "util"
version = "0.1.0"
source = "git+https://git.yukiri.dev/Yukiri/util.git#78391c67919071f9c53e5a05d8385ba6f8bbc9c1"

View File

@ -1,8 +1,10 @@
[package]
name = "szun"
version = "0.1.0"
repository = "https://git.yukiri.dev/Suzu/szun"
license-file = "LICENSE.md"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
publish = false
[dependencies]
stdu = { package = "util", git = "https://git.yukiri.dev/Yukiri/util.git" }

1
LICENSE.md Normal file
View File

@ -0,0 +1 @@
https://ykr.info/license/

View File

@ -1,7 +1,9 @@
fn main()
{
let d = szun::Integer::from(-1);
let enc = d.encode();
/* let mut sz = szun::init();
for b in enc { print!("{:02x}", b); } print!("\n");
let ob = sz.string("false");
let enc = sz.encode(ob).unwrap();
for b in enc { print!("{:02x}", b); } print!("\n"); */
}

View File

@ -1,19 +0,0 @@
use crate::{Szun, Type};
pub struct Boolean {
data:bool,
}
impl Boolean {
pub fn new() -> Szun
{
Szun::Boolean(false)
}
pub fn from(data:bool) -> Szun
{
Szun::Boolean(data)
}
}
impl Type for Boolean {
fn tag() -> u32 { 0x02 }
}

View File

@ -1,19 +0,0 @@
use crate::{Szun, Type};
pub struct Integer {
data:i64,
}
impl Integer {
pub fn new() -> Szun
{
Szun::Integer(0)
}
pub fn from(data:i64) -> Szun
{
Szun::Integer(data)
}
}
impl Type for Integer {
fn tag() -> u32 { 0x11 }
}

View File

@ -1,4 +0,0 @@
mod null; pub use null::Null;
mod boolean; pub use boolean::Boolean;
mod natural; pub use natural::Natural;
mod integer; pub use integer::Integer;

View File

@ -1,19 +0,0 @@
use crate::{Szun, Type};
pub struct Natural {
data:u64,
}
impl Natural {
pub fn new() -> Szun
{
Szun::Natural(0)
}
pub fn from(data:u64) -> Szun
{
Szun::Natural(data)
}
}
impl Type for Natural {
fn tag() -> u32 { 0x10 }
}

View File

@ -1,11 +0,0 @@
use crate::{Szun, Type};
pub struct Null { }
impl Null {
pub fn new() -> Szun {
Szun::Null
}
}
impl Type for Null {
fn tag() -> u32 { 0x00 }
}

View File

@ -1,129 +1,233 @@
#![allow(dead_code)]
mod util;
mod template; use template::Type;
mod data; pub use data::*;
pub enum Szun {
Null,
Boolean(bool),
Natural(u64),
Integer(i64),
Decimal(f64),
Block(Vec<u8>),
String(String),
Set(Vec<Szun>),
Array(Vec<Szun>),
List(Vec<Szun>),
Sparse(Vec<Szun>),
Map(Vec<Szun>),
//Tree(Vec<Szun>),
//Graph(Vec<Szun>),
Enum(Vec<Szun>),
Selection(Vec<Szun>),
Record(Vec<Szun>),
Schema(Vec<Szun>),
pub fn init() -> Interface { Interface::new() }
type Class = u8;
type Handle = u64;
const TAG_UNDEFINED :Class = 0x00;
const TAG_NULL :Class = 0x01;
const TAG_BOOLEAN :Class = 0x02;
//...
const TAG_NATURAL :Class = 0x10;
const TAG_INTEGER :Class = 0x11;
const TAG_DECIMAL :Class = 0x12;
//...
const TAG_BLOCK :Class = 0x1e;
const TAG_STRING :Class = 0x1f;
const TAG_OPTION :Class = 0x20;
const TAG_SET :Class = 0x21;
const TAG_ARRAY :Class = 0x22;
const TAG_LIST :Class = 0x23;
const TAG_SPARSE :Class = 0x24;
const TAG_MAP :Class = 0x25;
const TAG_TREE :Class = 0x26;
const TAG_GRAPH :Class = 0x27;
//...
const TAG_RECORD :Class = 0x3e;
const TAG_SCHEMA :Class = 0x3f;
fn mask_tag (tag:Class) -> Handle { (tag as u64) << 56 }
fn unmask_tag (handle:Handle) -> Class { (handle >> 56) as Class }
fn handle_id (handle:Handle) -> usize { (handle & !mask_tag(0xff)) as usize }
struct Container<T> {
pub class:Vec<Class>,
pub data:T,
}
impl Szun {
fn encode_parts(&self) -> (Vec<u32>, Vec<u8>)
pub struct Interface {
pool_boolean:stdu::Pool<bool>,
pool_natural:stdu::Pool<u64>,
pool_integer:stdu::Pool<i64>,
pool_block:stdu::Pool<Vec<u8>>,
pool_string:stdu::Pool<String>,
pool_option:stdu::Pool<Container<Option<Handle>>>,
pool_array:stdu::Pool<Container<Vec<Handle>>>,
pool_list:stdu::Pool<Container<Vec<Handle>>>,
pool_sparse:stdu::Pool<Container<stdu::Sparse<Handle>>>,
}
impl Interface {
pub(crate) fn new() -> Self
{
let mut tags = Vec::<u32>::with_capacity(1);
let mut encoded = Vec::<u8>::with_capacity(64);
match self {
Self::Null => {
tags.push(Null::tag());
Self {
pool_boolean:stdu::Pool::<bool>::new(),
pool_natural:stdu::Pool::<u64>::new(),
pool_integer:stdu::Pool::<i64>::new(),
pool_block:stdu::Pool::<Vec<u8>>::new(),
pool_string:stdu::Pool::<String>::new(),
pool_option:stdu::Pool::<Container<Option<Handle>>>::new(),
pool_array:stdu::Pool::<Container<Vec<Handle>>>::new(),
pool_list:stdu::Pool::<Container<Vec<Handle>>>::new(),
pool_sparse:stdu::Pool::<Container<stdu::Sparse<Handle>>>::new(),
}
}
Self::Boolean(_data) => {
tags.push(Boolean::tag());
/* DATA CONSTRUCTORS */
pub fn boolean(&mut self, value:bool) -> Handle {
mask_tag(TAG_BOOLEAN) + self.pool_boolean.add(value) as Handle
}
Self::Natural(data) => {
tags.push(Natural::tag());
encoded.append(&mut util::pack_natural(*data));
pub fn natural(&mut self, value:u64) -> Handle {
mask_tag(TAG_NATURAL) + self.pool_natural.add(value) as Handle
}
Self::Integer(data) => {
tags.push(Integer::tag());
encoded.append(&mut &mut util::pack_integer(*data));
pub fn integer(&mut self, value:i64) -> Handle {
mask_tag(TAG_INTEGER) + self.pool_integer.add(value) as Handle
}
_ => {
tags.push(0);
pub fn block(&mut self, value:&Vec<u8>) -> Handle {
mask_tag(TAG_BLOCK) + self.pool_block.add(value.clone()) as Handle
}
/*Self::Decimal(_data) => {
tag = Decimal::tag();
pub fn string(&mut self, value:&str) -> Handle {
mask_tag(TAG_STRING) + self.pool_string.add(value.to_string()) as Handle
}
Self::Block(_data) => {
tag = Block::tag();
}
Self::String(_data) => {
tag = String::tag();
}
/* ENCODING/DECODING */
Self::Set(_data) => {
tag = Set::tag();
}
Self::Array(_data) => {
tag = Array::tag();
}
Self::List(_data) => {
tag = List::tag();
}
Self::Sparse(_data) => {
tag = Sparse::tag();
}
Self::Map(_data) => {
tag = Map::tag();
}
Self::Enum(_data) => {
tag = Enum::tag();
}
Self::Selection(_data) => {
tag = Selection::tag();
}
Self::Record(_data) => {
tag = Record::tag();
}
Self::Schema(_data) => {
tag = Schema::tag();
}*/
}
return (tags, encoded);
}
pub fn encode_data(&self) -> Vec<u8>
fn encode_tags(tags:Vec<Class>) -> Vec<u8>
{
let (_, encoded) = self.encode_parts();
let mut encoded = Vec::<u8>::with_capacity(16);
for tag in tags {
encoded.append(&mut util::pack_natural(tag as u64));
}
return encoded;
}
pub fn encode(&self) -> Vec<u8>
fn encode_parts(&self, handle:Handle) -> Result<(Vec<Class>, Vec<u8>), ()>
{
let (tags, data) = self.encode_parts();
let mut prefix = Vec::<u8>::with_capacity(16);
let mut tags = Vec::<Class>::with_capacity(3);
let mut encoded = Vec::<u8>::with_capacity(64);
for tag in tags {
prefix.append(&mut util::pack_natural(tag as u64));
match unmask_tag(handle) {
TAG_NULL => {
tags.push(TAG_NULL);
}
TAG_BOOLEAN => match self.pool_boolean.get(handle_id(handle)) {
Some(value) => {
tags.push(TAG_BOOLEAN + *value as Class);
}
None => { return Err(()); }
}
TAG_NATURAL => match self.pool_natural.get(handle_id(handle)) {
Some(value) => {
tags.push(TAG_NATURAL);
encoded.append(&mut util::pack_natural(*value));
}
None => { return Err(()); }
}
TAG_INTEGER => match self.pool_integer.get(handle_id(handle)) {
Some(value) => {
tags.push(TAG_INTEGER);
encoded.append(&mut util::pack_integer(*value));
}
None => { return Err(()); }
}
TAG_BLOCK => match self.pool_block.get(handle_id(handle)) {
Some(data) => {
tags.push(TAG_BLOCK);
for b in data {
encoded.push(*b);
}
}
None => { return Err(()); }
}
TAG_STRING => match self.pool_string.get(handle_id(handle)) {
Some(data) => {
tags.push(TAG_STRING);
let mut bytes = Vec::<u8>::from(data.as_bytes());
encoded.append(&mut util::pack_natural(bytes.len() as u64));
encoded.append(&mut bytes);
}
None => { return Err(()); }
}
TAG_ARRAY => match self.pool_array.get(handle_id(handle)) {
Some(object) => {
tags.push(TAG_ARRAY);
tags.append(&mut object.class.clone());
}
None => { return Err(()); }
}
TAG_LIST => match self.pool_list.get(handle_id(handle)) {
Some(object) => {
tags.push(TAG_LIST);
tags.append(&mut object.class.clone());
}
None => { return Err(()); }
}
TAG_SPARSE => match self.pool_sparse.get(handle_id(handle)) {
Some(object) => {
tags.push(TAG_SPARSE);
tags.append(&mut object.class.clone());
// lookup table
// data table
}
None => { return Err(()); }
}
_ => { return Err(()); }
}
Err(())
}
pub fn encode_data(&self, handle:Handle) -> Result<Vec<u8>,()>
{
match self.encode_parts(handle) {
Ok((_, encoded)) => Ok(encoded),
Err(_) => Err(())
}
}
pub fn encode(&self, handle:Handle) -> Result<Vec<u8>,()>
{
match self.encode_parts(handle) {
Ok((tags, data)) => {
let prefix = Self::encode_tags(tags);
let mut encoded = Vec::<u8>::with_capacity(prefix.len() + data.len());
for b in prefix { encoded.push(b); }
for b in data { encoded.push(b); }
return encoded;
Ok(encoded)
}
Err(_) => Err(())
}
}
fn decode_tags(data:&Vec<u8>, index:&mut usize) -> Vec<Class>
{
let mut tags = Vec::<Class>::new();
while *index < data.len() {
let tag = util::unpack_natural(data, index) as Class;
tags.push(tag);
match tag {
TAG_ARRAY | TAG_LIST | TAG_SPARSE |TAG_RECORD => { }
_ => { break; }
}
}
return tags;
}
pub fn decode(&mut self, data:&Vec<u8>) -> Result<Handle,()>
{
let mut index :usize = 0;
let tags = Self::decode_tags(data, &mut index);
for tag in tags {
println!("{}", tag);
}
Err(())
}
}

View File

@ -0,0 +1,16 @@
use crate::{Instance, Handle};
#[derive(Clone)]
pub struct ArrayData {
pub class:u32,
pub data:Vec<Handle>,
}
pub struct Array<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Array<'a> {
pub fn tag() -> u32 { 0x21 }
}

View File

@ -0,0 +1,66 @@
use crate::{Instance, Szun};
pub struct Block<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Block<'a> {
pub fn tag() -> u32 { 0x1e }
fn acquire(&self) -> Option<&Vec<u8>>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::Block(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut Vec<u8>>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::Block(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> Vec<u8>
{
return match self.acquire() {
Some(data) => data.clone(),
None => vec![],
}
}
pub fn get_ref(&self) -> Option<&Vec<u8>>
{
return match self.acquire() {
Some(data) => Some(data),
None => None,
}
}
pub fn get_mut(&mut self) -> Option<&mut Vec<u8>>
{
return match self.acquire_mut() {
Some(data) => Some(data),
None => None,
}
}
pub fn set(&mut self, value:Vec<u8>)
{
match self.acquire_mut() {
Some(data) => { *data = value; }
None => { }
}
}
}

View File

@ -0,0 +1,74 @@
use crate::{Instance, Szun};
pub struct Boolean<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Boolean<'a> {
pub fn tag() -> u32 { 0x02 }
fn acquire(&self) -> Option<&bool>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::Boolean(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut bool>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::Boolean(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> bool
{
return match self.acquire() {
Some(data) => *data,
None => false,
}
}
pub fn get_mut(&mut self) -> Option<&mut bool>
{
return match self.acquire_mut() {
Some(data) => Some(data),
None => None,
}
}
pub fn set(&mut self)
{
match self.acquire_mut() {
Some(data) => { *data = true; }
None => { }
}
}
pub fn unset(&mut self)
{
match self.acquire_mut() {
Some(data) => { *data = false; }
None => { }
}
}
pub fn toggle(&mut self)
{
match self.acquire_mut() {
Some(data) => { *data = !*data; }
None => { }
}
}
}

View File

@ -0,0 +1,58 @@
use crate::{Instance, Szun};
pub struct Integer<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Integer<'a> {
pub fn tag() -> u32 { 0x11 }
fn acquire(&self) -> Option<&i64>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::Integer(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut i64>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::Integer(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> i64
{
return match self.acquire() {
Some(data) => *data,
None => 0,
}
}
pub fn get_mut(&mut self) -> Option<&mut i64>
{
return match self.acquire_mut() {
Some(data) => Some(data),
None => None,
}
}
pub fn set(&mut self, value:i64)
{
match self.acquire_mut() {
Some(data) => { *data = value; }
None => { }
}
}
}

90
src/old/interface/list.rs Normal file
View File

@ -0,0 +1,90 @@
use crate::{Instance, Szun, Handle};
#[derive(Clone)]
pub struct ListData {
pub class:u32,
pub data:Vec<Handle>,
}
pub struct List<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> List<'a> {
pub fn tag() -> u32 { 0x22 }
fn acquire(&self) -> Option<&ListData>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::List(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut ListData>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::List(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> Vec<Handle>
{
return match self.acquire() {
Some(data) => data.data.clone(),
None => vec![],
}
}
pub fn get_ref(&self) -> Option<&Vec<Handle>>
{
return match self.acquire() {
Some(data) => Some(&data.data),
None => None,
}
}
pub fn get_mut(&mut self) -> Option<&mut Vec<Handle>>
{
return match self.acquire_mut() {
Some(data) => Some(&mut data.data),
None => None,
}
}
pub fn set(&mut self, data:Vec<Handle>) -> Result<(),()>
{
/* return match self.acquire_mut() {
Some(ld) => {
let mut is_valid = true;
for handle in data {
match self.instance.data.get(handle) {
Some(entry) => {
if entry.object.tag() != ld.class && ld.class != 0 { is_valid = false; break; }
}
None => { is_valid = false; break; }
}
}
if is_valid {
ld.data = data;
Ok(())
} else {
Err(())
}
}
None => Err(())
} */
Err(())
}
}

9
src/old/interface/mod.rs Normal file
View File

@ -0,0 +1,9 @@
mod null; pub use null::*;
mod boolean; pub use boolean::*;
mod natural; pub use natural::*;
mod integer; pub use integer::*;
mod block; pub use block::*;
mod string; pub use string::*;
mod array; pub use array::*;
mod list; pub use list::*;
mod sparse; pub use sparse::*;

View File

@ -0,0 +1,58 @@
use crate::{Instance, Szun};
pub struct Natural<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Natural<'a> {
pub fn tag() -> u32 { 0x10 }
fn acquire(&self) -> Option<&u64>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::Natural(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut u64>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::Natural(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> u64
{
return match self.acquire() {
Some(data) => *data,
None => 0,
}
}
pub fn get_mut(&mut self) -> Option<&mut u64>
{
return match self.acquire_mut() {
Some(data) => Some(data),
None => None,
}
}
pub fn set(&mut self, value:u64)
{
match self.acquire_mut() {
Some(data) => { *data = value; }
None => { }
}
}
}

10
src/old/interface/null.rs Normal file
View File

@ -0,0 +1,10 @@
use crate::{Instance};
pub struct Null<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Null<'a> {
pub fn tag() -> u32 { 0x00 }
}

View File

@ -0,0 +1,16 @@
use crate::{Instance, Szun};
#[derive(Clone)]
pub struct SparseData {
pub class:u32,
pub data:stdu::Sparse<Szun>,
}
pub struct Sparse<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Sparse<'a> {
pub fn tag() -> u32 { 0x23 }
}

View File

@ -0,0 +1,10 @@
use crate::{Instance};
pub struct String<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> String<'a> {
pub fn tag() -> u32 { 0x1f }
}

309
src/old/lib.rs Normal file
View File

@ -0,0 +1,309 @@
#![allow(dead_code)]
mod util;
mod template; pub use template::Type;
mod interface; pub use interface::*;
pub type Class = u32;
pub type Handle = usize;
#[derive(Clone)]
pub enum Szun {
/*00*/ Null,
/*02*/ Boolean(bool),
/*10*/ Natural(u64),
/*11*/ Integer(i64),
/*12*/ //Decimal(f64),
/*20*/ Block(Vec<u8>),
/*21*/ String(std::string::String),
/*30*/ //Set(Set),
/*31*/ Array(ArrayData),
/*32*/ List(ListData),
/*33*/ Sparse(SparseData),
/*34*/ //Map(Map),
/*35*/ //Tree(Tree),
/*36*/ //Graph(Graph),
/*40*/ //Enum(Enum),
/*41*/ //Selection(Selection),
/*4e*/ //Record(Record),
/*4f*/ //Schema(Schema),
}
impl Szun {
pub fn tag(&self) -> Class
{
match self {
Self::Null => Null::tag(),
Self::Boolean(_) => Boolean::tag(),
Self::Natural(_) => Natural::tag(),
Self::Integer(_) => Integer::tag(),
Self::Block(_) => Block::tag(),
Self::String(_) => String::tag(),
Self::Array(_) => Array::tag(),
Self::List(_) => List::tag(),
Self::Sparse(_) => Sparse::tag(),
}
}
}
macro_rules! szun_as {
($name:ident, $class:pat, $impl:ident) => {
pub fn $name(&mut self, handle:usize) -> Option<$impl>
{
match self.data.get(handle) {
Some(object) => {
match object.object {
$class => { return Some($impl { instance: self, target: handle }); }
_ => { }
}
}
None => { }
}
return None;
}
};
}
pub fn init() -> Instance { Instance::new() }
struct Entry {
owner:Handle,
class:Class,
object:Szun,
}
impl Entry {
pub fn new(object:Szun) -> Self
{
Self {
owner:0,
class:0,
object:object,
}
}
pub fn new_classed(class:Class, object:Szun) -> Self
{
Self {
owner:0,
class:class,
object:object,
}
}
}
pub struct Instance {
pub(crate) schemas:stdu::Sparse<Szun>,
pub(crate) data:stdu::Pool<Entry>,
}
impl Instance {
pub(crate) fn new() -> Self
{
Self {
schemas:stdu::Sparse::<Szun>::new(),
data:stdu::Pool::<Entry>::new(),
}
}
pub fn null(&mut self) -> Handle { self.data.add(Entry::new(Szun::Null)) }
pub fn boolean(&mut self, data:bool) -> Handle { self.data.add(Entry::new(Szun::Boolean(data))) }
pub fn natural(&mut self, data:u64) -> Handle { self.data.add(Entry::new(Szun::Natural(data))) }
pub fn integer(&mut self, data:i64) -> Handle { self.data.add(Entry::new(Szun::Integer(data))) }
pub fn block(&mut self, data:Vec<u8>) -> Handle { self.data.add(Entry::new(Szun::Block(data))) }
pub fn string(&mut self, data:&str) -> Handle { self.data.add(Entry::new(Szun::String(data.to_string()))) }
//pub fn array(&mut self, data:Vec<Handle>) -> Handle { self.data.add(Szun::Array(data)) }
pub fn list(&mut self, class:Class, data:&Vec<Handle>) -> Option<Handle> {
for handle in data {
match self.data.get(*handle) {
Some(object) => {
if object.object.tag() != class && class != 0 { return None; }
}
None => { return None; }
}
}
let obj = Szun::List(ListData { class:class, data:data.clone() });
return Some(self.data.add(Entry::new(obj)));
}
//pub fn sparse(&mut self, data:stdu::Sparse<Handle>) -> Handle { self.data.add(Szun::Sparse(data)) }
szun_as!(as_null, Szun::Null, Null);
szun_as!(as_boolean, Szun::Boolean(_), Boolean);
szun_as!(as_natural, Szun::Natural(_), Natural);
szun_as!(as_integer, Szun::Integer(_), Integer);
szun_as!(as_block, Szun::Block(_), Block);
szun_as!(as_string, Szun::String(_), String);
fn encode_tags(tags:Vec<Class>) -> Vec<u8>
{
let mut encoded = Vec::<u8>::with_capacity(16);
for tag in tags {
encoded.append(&mut util::pack_natural(tag as u64));
}
return encoded;
}
fn encode_parts(&self, object:&Szun) -> Result<(Vec<Class>, Vec<u8>), ()>
{
let mut tags = Vec::<Class>::with_capacity(1);
let mut encoded = Vec::<u8>::with_capacity(64);
match object {
Szun::Null => {
tags.push(Null::tag());
}
Szun::Boolean(data) => {
tags.push(if *data { Boolean::tag() + 1 } else { Boolean::tag() });
}
Szun::Natural(data) => {
tags.push(Natural::tag());
encoded.append(&mut util::pack_natural(*data));
}
Szun::Integer(data) => {
tags.push(Integer::tag());
encoded.append(&mut &mut util::pack_integer(*data));
}
//Szun::Decimal(_data) => {
// tag = Decimal::tag();
//}
Szun::Block(data) => {
tags.push(Block::tag());
tags.push(data.len() as Class);
for b in data {
encoded.push(*b);
}
}
Szun::String(data) => {
tags.push(String::tag());
let mut bytes = Vec::<u8>::from(data.as_bytes());
let mut size = util::pack_natural(bytes.len() as u64);
encoded.append(&mut size);
encoded.append(&mut bytes);
}
//Szun::Set(_data) => {
// tag = Set::tag();
//}
Szun::Array(data) => {
tags.push(Array::tag());
tags.push(data.data.len() as Class);
tags.push(data.class);
for item in &data.data {
match self.data.get(*item) {
Some(entry) => {
match self.encode_parts(&entry.object) {
Ok((s_tags, mut s_data)) => {
if data.class == 0 {
encoded.append(&mut Self::encode_tags(s_tags));
}
encoded.append(&mut s_data);
}
Err(_) => { return Err(()); }
}
}
None => { return Err(()); }
}
}
}
Szun::List(data) => {
tags.push(List::tag());
tags.push(data.class);
encoded.append(&mut util::pack_natural(data.data.len() as u64));
for item in &data.data {
match self.data.get(*item) {
Some(entry) => {
match self.encode_parts(&entry.object) {
Ok((s_tags, mut s_data)) => {
if data.class == 0 {
encoded.append(&mut Self::encode_tags(s_tags));
}
encoded.append(&mut s_data);
}
Err(_) => { return Err(()); }
}
}
None => { return Err(()); }
}
}
}
Szun::Sparse(data) => {
tags.push(Sparse::tag());
tags.push(data.class);
encoded.append(&mut util::pack_natural(data.data.len() as u64));
//for item in &data {
// let (s_tags, mut s_data) = item.encode_parts();
// if data.class == 0 {
// encoded.append(&mut Szun::encode_tags(s_tags));
// }
// encoded.append(&mut s_data);
//}
}
/*Szun::Map(_data) => {
tag = Map::tag();
}
Szun::Enum(_data) => {
tag = Enum::tag();
}
Szun::Selection(_data) => {
tag = Selection::tag();
}
Szun::Record(_data) => {
tag = Record::tag();
}
Szun::Schema(_data) => {
tag = Schema::tag();
}*/
}
return Ok((tags, encoded));
}
pub fn encode_data(&self, handle:Handle) -> Result<Vec<u8>,()>
{
return match self.data.get(handle) {
Some(entry) => {
match self.encode_parts(&entry.object) {
Ok((_, encoded)) => Ok(encoded),
Err(_) => Err(())
}
}
None => Err(())
};
}
pub fn encode(&self, handle:Handle) -> Result<Vec<u8>,()>
{
return match self.data.get(handle) {
Some(entry) => {
match self.encode_parts(&entry.object) {
Ok((tags, data)) => {
let prefix = Self::encode_tags(tags);
let mut encoded = Vec::<u8>::with_capacity(prefix.len() + data.len());
for b in prefix { encoded.push(b); }
for b in data { encoded.push(b); }
Ok(encoded)
},
Err(_) => Err(())
}
}
None => Err(())
};
}
}