diff --git a/Cargo.lock b/Cargo.lock index a1740ea..c42c7e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 76b4d94..c61de3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" } diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..e9ca222 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1 @@ +https://ykr.info/license/ diff --git a/src/bin/main.rs b/src/bin/main.rs index 778d05a..26fbdc2 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -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"); */ } diff --git a/src/data/boolean.rs b/src/data/boolean.rs deleted file mode 100644 index 8d842d1..0000000 --- a/src/data/boolean.rs +++ /dev/null @@ -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 } -} diff --git a/src/data/integer.rs b/src/data/integer.rs deleted file mode 100644 index fc4484d..0000000 --- a/src/data/integer.rs +++ /dev/null @@ -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 } -} diff --git a/src/data/mod.rs b/src/data/mod.rs deleted file mode 100644 index 2e054e6..0000000 --- a/src/data/mod.rs +++ /dev/null @@ -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; diff --git a/src/data/natural.rs b/src/data/natural.rs deleted file mode 100644 index 4c7984b..0000000 --- a/src/data/natural.rs +++ /dev/null @@ -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 } -} diff --git a/src/data/null.rs b/src/data/null.rs deleted file mode 100644 index f020364..0000000 --- a/src/data/null.rs +++ /dev/null @@ -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 } -} diff --git a/src/lib.rs b/src/lib.rs index 83fe9e9..53aefe7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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), - String(String), - Set(Vec), - Array(Vec), - List(Vec), - Sparse(Vec), - Map(Vec), - //Tree(Vec), - //Graph(Vec), - Enum(Vec), - Selection(Vec), - Record(Vec), - Schema(Vec), -} -impl Szun { - fn encode_parts(&self) -> (Vec, Vec) - { - let mut tags = Vec::::with_capacity(1); - let mut encoded = Vec::::with_capacity(64); - - match self { - Self::Null => { - tags.push(Null::tag()); - } - - Self::Boolean(_data) => { - tags.push(Boolean::tag()); - } - - Self::Natural(data) => { - tags.push(Natural::tag()); - encoded.append(&mut util::pack_natural(*data)); - } - - Self::Integer(data) => { - tags.push(Integer::tag()); - encoded.append(&mut &mut util::pack_integer(*data)); - } - - _ => { - tags.push(0); - } - - /*Self::Decimal(_data) => { - tag = Decimal::tag(); - } - - Self::Block(_data) => { - tag = Block::tag(); - } - - Self::String(_data) => { - tag = String::tag(); - } - - 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 - { - let (_, encoded) = self.encode_parts(); - return encoded; - } - - pub fn encode(&self) -> Vec - { - let (tags, data) = self.encode_parts(); - let mut prefix = Vec::::with_capacity(16); - - for tag in tags { - prefix.append(&mut util::pack_natural(tag as u64)); - } - - let mut encoded = Vec::::with_capacity(prefix.len() + data.len()); - for b in prefix { encoded.push(b); } - for b in data { encoded.push(b); } - - return encoded; - } -} +#![allow(dead_code)] + +mod util; + +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 { + pub class:Vec, + pub data:T, +} + +pub struct Interface { + pool_boolean:stdu::Pool, + pool_natural:stdu::Pool, + pool_integer:stdu::Pool, + pool_block:stdu::Pool>, + pool_string:stdu::Pool, + pool_option:stdu::Pool>>, + pool_array:stdu::Pool>>, + pool_list:stdu::Pool>>, + pool_sparse:stdu::Pool>>, +} +impl Interface { + pub(crate) fn new() -> Self + { + Self { + pool_boolean:stdu::Pool::::new(), + pool_natural:stdu::Pool::::new(), + pool_integer:stdu::Pool::::new(), + pool_block:stdu::Pool::>::new(), + pool_string:stdu::Pool::::new(), + pool_option:stdu::Pool::>>::new(), + pool_array:stdu::Pool::>>::new(), + pool_list:stdu::Pool::>>::new(), + pool_sparse:stdu::Pool::>>::new(), + } + } + + + /* DATA CONSTRUCTORS */ + + pub fn boolean(&mut self, value:bool) -> Handle { + mask_tag(TAG_BOOLEAN) + self.pool_boolean.add(value) as Handle + } + + pub fn natural(&mut self, value:u64) -> Handle { + mask_tag(TAG_NATURAL) + self.pool_natural.add(value) as Handle + } + + pub fn integer(&mut self, value:i64) -> Handle { + mask_tag(TAG_INTEGER) + self.pool_integer.add(value) as Handle + } + + pub fn block(&mut self, value:&Vec) -> Handle { + mask_tag(TAG_BLOCK) + self.pool_block.add(value.clone()) as Handle + } + + pub fn string(&mut self, value:&str) -> Handle { + mask_tag(TAG_STRING) + self.pool_string.add(value.to_string()) as Handle + } + + + /* ENCODING/DECODING */ + + fn encode_tags(tags:Vec) -> Vec + { + let mut encoded = Vec::::with_capacity(16); + for tag in tags { + encoded.append(&mut util::pack_natural(tag as u64)); + } + return encoded; + } + + fn encode_parts(&self, handle:Handle) -> Result<(Vec, Vec), ()> + { + let mut tags = Vec::::with_capacity(3); + let mut encoded = Vec::::with_capacity(64); + + 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::::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,()> + { + match self.encode_parts(handle) { + Ok((_, encoded)) => Ok(encoded), + Err(_) => Err(()) + } + } + + pub fn encode(&self, handle:Handle) -> Result,()> + { + match self.encode_parts(handle) { + Ok((tags, data)) => { + let prefix = Self::encode_tags(tags); + let mut encoded = Vec::::with_capacity(prefix.len() + data.len()); + for b in prefix { encoded.push(b); } + for b in data { encoded.push(b); } + + Ok(encoded) + } + Err(_) => Err(()) + } + } + + fn decode_tags(data:&Vec, index:&mut usize) -> Vec + { + let mut tags = Vec::::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) -> Result + { + let mut index :usize = 0; + let tags = Self::decode_tags(data, &mut index); + + for tag in tags { + println!("{}", tag); + } + + Err(()) + } +} diff --git a/src/old/interface/array.rs b/src/old/interface/array.rs new file mode 100644 index 0000000..6dc4647 --- /dev/null +++ b/src/old/interface/array.rs @@ -0,0 +1,16 @@ +use crate::{Instance, Handle}; + +#[derive(Clone)] +pub struct ArrayData { + pub class:u32, + pub data:Vec, +} + +pub struct Array<'a> { + pub(crate) instance:&'a mut Instance, + pub(crate) target:usize, +} +impl<'a> Array<'a> { + pub fn tag() -> u32 { 0x21 } + +} diff --git a/src/old/interface/block.rs b/src/old/interface/block.rs new file mode 100644 index 0000000..71fa083 --- /dev/null +++ b/src/old/interface/block.rs @@ -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> + { + 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> + { + 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 + { + return match self.acquire() { + Some(data) => data.clone(), + None => vec![], + } + } + + pub fn get_ref(&self) -> Option<&Vec> + { + return match self.acquire() { + Some(data) => Some(data), + None => None, + } + } + + pub fn get_mut(&mut self) -> Option<&mut Vec> + { + return match self.acquire_mut() { + Some(data) => Some(data), + None => None, + } + } + + pub fn set(&mut self, value:Vec) + { + match self.acquire_mut() { + Some(data) => { *data = value; } + None => { } + } + } +} diff --git a/src/old/interface/boolean.rs b/src/old/interface/boolean.rs new file mode 100644 index 0000000..9e6b590 --- /dev/null +++ b/src/old/interface/boolean.rs @@ -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 => { } + } + } +} diff --git a/src/old/interface/integer.rs b/src/old/interface/integer.rs new file mode 100644 index 0000000..6f5b253 --- /dev/null +++ b/src/old/interface/integer.rs @@ -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 => { } + } + } +} diff --git a/src/old/interface/list.rs b/src/old/interface/list.rs new file mode 100644 index 0000000..60ab5fb --- /dev/null +++ b/src/old/interface/list.rs @@ -0,0 +1,90 @@ +use crate::{Instance, Szun, Handle}; + +#[derive(Clone)] +pub struct ListData { + pub class:u32, + pub data:Vec, +} + +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 + { + return match self.acquire() { + Some(data) => data.data.clone(), + None => vec![], + } + } + + pub fn get_ref(&self) -> Option<&Vec> + { + return match self.acquire() { + Some(data) => Some(&data.data), + None => None, + } + } + + pub fn get_mut(&mut self) -> Option<&mut Vec> + { + return match self.acquire_mut() { + Some(data) => Some(&mut data.data), + None => None, + } + } + + pub fn set(&mut self, data:Vec) -> 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(()) + } +} diff --git a/src/old/interface/mod.rs b/src/old/interface/mod.rs new file mode 100644 index 0000000..816a137 --- /dev/null +++ b/src/old/interface/mod.rs @@ -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::*; diff --git a/src/old/interface/natural.rs b/src/old/interface/natural.rs new file mode 100644 index 0000000..311bba1 --- /dev/null +++ b/src/old/interface/natural.rs @@ -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 => { } + } + } +} diff --git a/src/old/interface/null.rs b/src/old/interface/null.rs new file mode 100644 index 0000000..94ab7a5 --- /dev/null +++ b/src/old/interface/null.rs @@ -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 } + +} diff --git a/src/old/interface/sparse.rs b/src/old/interface/sparse.rs new file mode 100644 index 0000000..260f27d --- /dev/null +++ b/src/old/interface/sparse.rs @@ -0,0 +1,16 @@ +use crate::{Instance, Szun}; + +#[derive(Clone)] +pub struct SparseData { + pub class:u32, + pub data:stdu::Sparse, +} + +pub struct Sparse<'a> { + pub(crate) instance:&'a mut Instance, + pub(crate) target:usize, +} +impl<'a> Sparse<'a> { + pub fn tag() -> u32 { 0x23 } + +} diff --git a/src/old/interface/string.rs b/src/old/interface/string.rs new file mode 100644 index 0000000..4d270f3 --- /dev/null +++ b/src/old/interface/string.rs @@ -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 } + +} diff --git a/src/old/lib.rs b/src/old/lib.rs new file mode 100644 index 0000000..dd10854 --- /dev/null +++ b/src/old/lib.rs @@ -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), + /*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, + pub(crate) data:stdu::Pool, +} +impl Instance { + pub(crate) fn new() -> Self + { + Self { + schemas:stdu::Sparse::::new(), + data:stdu::Pool::::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) -> 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 { self.data.add(Szun::Array(data)) } + pub fn list(&mut self, class:Class, data:&Vec) -> Option { + 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 { 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) -> Vec + { + let mut encoded = Vec::::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, Vec), ()> + { + let mut tags = Vec::::with_capacity(1); + let mut encoded = Vec::::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::::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,()> + { + 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,()> + { + 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::::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(()) + }; + } +} diff --git a/src/template/mod.rs b/src/old/template/mod.rs similarity index 100% rename from src/template/mod.rs rename to src/old/template/mod.rs