diff --git a/README.md b/README.md index bf49278..51d2b06 100644 --- a/README.md +++ b/README.md @@ -621,8 +621,6 @@ Returns the key of the element at the specified index. ## Schema Definition of an abstract structure composed of named items. -> Encode/decode not implemented. - `with(members:Vec<(&str, usize)>) -> Schema` Produces a schema with the provided member assignments. diff --git a/src/encoding/mod.rs b/src/encoding/mod.rs index 380609d..45acda5 100644 --- a/src/encoding/mod.rs +++ b/src/encoding/mod.rs @@ -14,25 +14,27 @@ use crate::{ Varying, Boolean, Natural, Integer, + //Significant, Block, Sequence, Array, List, Record, + Schema, }; use crate::util; -pub fn encode_tag(addr:Reference) -> Vec +pub fn encode_tag(type_id:usize) -> Vec { - let mut type_id = addr.class; + let mut tid = type_id; let mut result = Vec::::new(); let mut remaining :usize = 1; while remaining > 0 { - result.append(&mut util::pack_natural(unsafe {type_key(type_id)} as u64)); + result.append(&mut util::pack_natural(unsafe {type_key(tid)} as u64)); remaining -= 1; if remaining == 0 { - remaining += unsafe {type_hasinner(type_id)}; + remaining += unsafe {type_hasinner(tid)}; } - type_id = unsafe {type_inner(type_id)}; + tid = unsafe {type_inner(tid)}; } return result; } @@ -54,6 +56,9 @@ pub fn encode_data(addr:Reference) -> Vec tag::INTEGER => { result.append(&mut &mut util::pack_integer(Integer::from(addr).unwrap().get() as i64)); } + tag::SIGNIFICANT => { + result.append(&mut vec![0]); + } tag::BLOCK => { result.append(&mut Block::from(addr).unwrap().get()); } @@ -119,6 +124,19 @@ pub fn encode_data(addr:Reference) -> Vec } } } + tag::SCHEMA => { + let data = Schema::from(addr).unwrap(); + + result.append(&mut util::pack_natural(data.length() as u64)); + + for i in 0..data.length() { + result.append(&mut encode_tag(data.get(i).unwrap())); + + let mut key = Vec::from(data.keyof(i).unwrap().as_bytes()); + result.append(&mut util::pack_natural(key.len() as u64)); + result.append(&mut key); + } + } _ => { } } return result; @@ -126,7 +144,7 @@ pub fn encode_data(addr:Reference) -> Vec pub fn encode(addr:Reference) -> Vec { - let mut result = encode_tag(addr); + let mut result = encode_tag(addr.class); result.append(&mut encode_data(addr)); return result; } @@ -173,6 +191,9 @@ pub fn decode_data(data:&Vec, type_id:usize, index:&mut usize) -> Result { return Ok(Type::Integer(Integer::with(unpack_integer(data, index)))); } + tag::SIGNIFICANT => { + return Err(()) + } tag::BLOCK => { let size = unsafe {type_innerkey(type_id)}; let mut bytes = Vec::::with_capacity(size); @@ -281,6 +302,36 @@ pub fn decode_data(data:&Vec, type_id:usize, index:&mut usize) -> Result Err(()), } } + tag::SCHEMA => { + let mut result = Schema::new(); + + let length = util::unpack_natural(data, index) as usize; + + for _ in 0..length { + let class :usize; + match decode_tag(data, index) { + Ok(tag) => { class = tag; } + Err(_) => { return Err(()); } + } + + let key_length = util::unpack_natural(data, index) as usize; + let mut key_bytes = Vec::::with_capacity(key_length); + for _ in 0..key_length { + if *index < data.len() { + key_bytes.push(data[*index]); + *index += 1; + } + else { + return Err(()); + } + } + let key = String::from_utf8(key_bytes).unwrap(); + + result.assign(&key, class); + } + + return Ok(Type::Schema(result)); + } _ => { } } diff --git a/src/interface/schema.rs b/src/interface/schema.rs index 0052722..23f57b9 100644 --- a/src/interface/schema.rs +++ b/src/interface/schema.rs @@ -102,7 +102,7 @@ impl Schema { unsafe { schema_unmap(self.addr, key_index); } } - pub fn indexof(&mut self, key:&str) -> Option + pub fn indexof(&self, key:&str) -> Option { let key_index = name_indexof(key); let result = unsafe {schema_indexof(self.addr, key_index)}; @@ -114,7 +114,7 @@ impl Schema { } } - pub fn keyof(&mut self, index:usize) -> Option + pub fn keyof(&self, index:usize) -> Option { let result = unsafe {schema_keyof(self.addr, index)}; if result != 0 { diff --git a/src/lib.rs b/src/lib.rs index f0b9ed1..2c22aa1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,14 +20,15 @@ pub fn test() { ]).bind(MAGAZINE_ROW); // define schema "Magazine" - Schema::with(vec![ + let magazine = Schema::with(vec![ ("Capacity", natural()), ("Quantity", natural()), ("Content", list(record(MAGAZINE_ROW))), - ]).bind(MAGAZINE); + ]); + magazine.bind(MAGAZINE); // create record "Magazine" - let data = Record::with(MAGAZINE, vec![ + let _data = Record::with(MAGAZINE, vec![ ("Capacity", *Natural::with(30)), ("Quantity", *Natural::with(25)), ("Content", *List::with(record(MAGAZINE_ROW), vec![ @@ -43,10 +44,10 @@ pub fn test() { ]).unwrap(); // encode record - let out = encode(*data); + let out = encode(*magazine); // write encoding to file - let mut file = File::create("dat.szn").unwrap(); + let mut file = File::create("target/dat.szn").unwrap(); file.write_all(&out).ok(); // print hex series of encoding @@ -54,6 +55,19 @@ pub fn test() { for byte in &out { print!("{:02x} ", *byte); } println!(""); + + match decode(&out, &mut 0) { + Ok(t) => match t { + Type::Schema(data) => { + println!("len: {}", data.length()); + for i in 0..data.length() { + println!("'{}': {} ({:02x})", data.keyof(i).unwrap(), data.get(i).unwrap(), kind(data.get(i).unwrap())); + } + } + _ => { println!("not expected"); } + } + Err(_) => { println!("failed"); } + } } #[cfg(test)] diff --git a/src/tests/array.rs b/src/tests/array.rs new file mode 100644 index 0000000..45f8160 --- /dev/null +++ b/src/tests/array.rs @@ -0,0 +1,38 @@ +use crate::*; + +#[test] +fn array_initialize() +{ + let _data = Array::new(4, natural()); + +} + +#[test] +fn array_from() +{ + +} + +#[test] +fn array_with() +{ + +} + +#[test] +fn array_length() +{ + +} + +#[test] +fn array_at() +{ + +} + +#[test] +fn array_set() +{ + +} diff --git a/src/tests/block.rs b/src/tests/block.rs new file mode 100644 index 0000000..efe9fa8 --- /dev/null +++ b/src/tests/block.rs @@ -0,0 +1,17 @@ +use crate::*; + +#[test] +fn block_initialize() +{ + let value = Block::new(8); + assert_eq!(8, value.size(), "Block::new(8) has length of 8."); + assert_eq!(vec![0;8], value.get(), "Block::new(8) has value of 0."); +} + +#[test] +fn block_set_get() +{ + let mut value = Block::new(4); + value.set(vec![1, 2, 3, 4]); + assert_eq!(vec![1, 2, 3, 4], value.get(), "Block::set([1,2,3,4]) has value of [1,2,3,4]."); +} diff --git a/src/tests/boolean.rs b/src/tests/boolean.rs new file mode 100644 index 0000000..65769c3 --- /dev/null +++ b/src/tests/boolean.rs @@ -0,0 +1,25 @@ +use crate::*; + +#[test] +fn boolean_initialize() +{ + let value = Boolean::new(); + assert_eq!(false, value.get(), "Boolean::new() produces value of false."); +} + +#[test] +fn boolean_with() +{ + assert_eq!(false, Boolean::with(false).get(), "Boolean::with(false) produces value of false."); + assert_eq!(true, Boolean::with(true).get(), "Boolean::with(true) produces value of true."); +} + +#[test] +fn boolean_set_get() +{ + let mut value = Boolean::new(); + value.set(true); + assert_eq!(true, value.get(), "Boolean.set(true) produces value of true."); + value.set(false); + assert_eq!(false, value.get(), "Boolean.set(false) produces value of false."); +} diff --git a/src/tests/integer.rs b/src/tests/integer.rs new file mode 100644 index 0000000..7b91328 --- /dev/null +++ b/src/tests/integer.rs @@ -0,0 +1,18 @@ +use crate::*; + +#[test] +fn integer_initialize() +{ + let value = Integer::new(); + assert_eq!(0, value.get(), "Integer::new() produces value of 0."); +} + +#[test] +fn integer_set_get() +{ + let mut value = Integer::new(); + value.set(-273); + assert_eq!(-273, value.get(), "Integer.set(-273) produces value of -273."); + value.set(100); + assert_eq!(100, value.get(), "Integer.set(100) produces value of 100."); +} diff --git a/src/tests.rs b/src/tests/list.rs similarity index 55% rename from src/tests.rs rename to src/tests/list.rs index f98d41d..ac8f315 100644 --- a/src/tests.rs +++ b/src/tests/list.rs @@ -1,140 +1,5 @@ use crate::*; -#[test] -fn boolean_initialize() -{ - let value = Boolean::new(); - assert_eq!(false, value.get(), "Boolean::new() produces value of false."); -} - -#[test] -fn boolean_with() -{ - assert_eq!(false, Boolean::with(false).get(), "Boolean::with(false) produces value of false."); - assert_eq!(true, Boolean::with(true).get(), "Boolean::with(true) produces value of true."); -} - -#[test] -fn boolean_set_get() -{ - let mut value = Boolean::new(); - value.set(true); - assert_eq!(true, value.get(), "Boolean.set(true) produces value of true."); - value.set(false); - assert_eq!(false, value.get(), "Boolean.set(false) produces value of false."); -} - -#[test] -fn natural_initialize() -{ - let value = Natural::new(); - assert_eq!(0, value.get(), "Natural::new() produces value of 0."); -} - -#[test] -fn natural_set_get() -{ - let mut value = Natural::new(); - value.set(12); - assert_eq!(12, value.get(), "Natural.set(12) produces value of 12."); - value.set(38695); - assert_eq!(38695, value.get(), "Natural.set(38695) produces value of 38695."); -} - -#[test] -fn integer_initialize() -{ - let value = Integer::new(); - assert_eq!(0, value.get(), "Integer::new() produces value of 0."); -} - -#[test] -fn integer_set_get() -{ - let mut value = Integer::new(); - value.set(-273); - assert_eq!(-273, value.get(), "Integer.set(-273) produces value of -273."); - value.set(100); - assert_eq!(100, value.get(), "Integer.set(100) produces value of 100."); -} - -#[test] -fn block_initialize() -{ - let value = Block::new(8); - assert_eq!(8, value.size(), "Block::new(8) has length of 8."); - assert_eq!(vec![0;8], value.get(), "Block::new(8) has value of 0."); -} - -#[test] -fn block_set_get() -{ - let mut value = Block::new(4); - value.set(vec![1, 2, 3, 4]); - assert_eq!(vec![1, 2, 3, 4], value.get(), "Block::set([1,2,3,4]) has value of [1,2,3,4]."); -} - -#[test] -fn sequence_initialize() -{ - let value = Sequence::new(); - assert_eq!(0, value.size(), "Sequence::new() has length 0."); -} - -#[test] -fn sequence_set_get_raw() -{ - let mut value = Sequence::new(); - value.set_raw(vec![0, 1, 2, 3, 2, 1]); - assert_eq!(6, value.size(), "Sequence.set_raw([0,1,2,3,2,1]) has length 6."); - assert_eq!(vec![0,1,2,3,2,1], value.get_raw(), "Sequence.set_raw([0,1,2,3,2,1]) produces value [0,1,2,3,2,1]."); -} - -#[test] -fn sequence_set_get_str() -{ - let mut value = Sequence::new(); - value.set("hello"); - assert_eq!(5, value.size(), "Sequence.set(hello) has length 5."); - assert_eq!(String::from("hello"), value.get(), "Sequence.set(hello) produces value hello."); -} - -#[test] -fn array_initialize() -{ - -} - -#[test] -fn array_from() -{ - -} - -#[test] -fn array_with() -{ - -} - -#[test] -fn array_length() -{ - -} - -#[test] -fn array_at() -{ - -} - -#[test] -fn array_set() -{ - -} - #[test] fn list_initialize() { @@ -267,45 +132,3 @@ fn list_reserve() list.reserve(capacity); assert_eq!(capacity, list.capacity(), "List has updated capacity."); } - -#[test] -fn record_initialize() -{ - -} - -#[test] -fn record_from() -{ - -} - -#[test] -fn record_with() -{ - -} - -#[test] -fn record_with_values() -{ - -} - -#[test] -fn record_at() -{ - -} - -#[test] -fn record_set() -{ - -} - -#[test] -fn schema_initialize() -{ - -} diff --git a/src/tests/mod.rs b/src/tests/mod.rs new file mode 100644 index 0000000..e8d8a81 --- /dev/null +++ b/src/tests/mod.rs @@ -0,0 +1,10 @@ +mod boolean; +mod natural; +mod integer; +mod block; +mod sequence; +mod array; +mod list; +mod sparse; +mod schema; +mod record; diff --git a/src/tests/natural.rs b/src/tests/natural.rs new file mode 100644 index 0000000..ff8a717 --- /dev/null +++ b/src/tests/natural.rs @@ -0,0 +1,18 @@ +use crate::*; + +#[test] +fn natural_initialize() +{ + let value = Natural::new(); + assert_eq!(0, value.get(), "Natural::new() produces value of 0."); +} + +#[test] +fn natural_set_get() +{ + let mut value = Natural::new(); + value.set(12); + assert_eq!(12, value.get(), "Natural.set(12) produces value of 12."); + value.set(38695); + assert_eq!(38695, value.get(), "Natural.set(38695) produces value of 38695."); +} diff --git a/src/tests/record.rs b/src/tests/record.rs new file mode 100644 index 0000000..458243a --- /dev/null +++ b/src/tests/record.rs @@ -0,0 +1,41 @@ +use crate::*; + +#[test] +fn record_initialize() +{ + Schema::with(vec![ + + ]).bind(20); + + let _data = Record::new(20); +} + +#[test] +fn record_from() +{ + +} + +#[test] +fn record_with() +{ + +} + +#[test] +fn record_with_values() +{ + +} + +#[test] +fn record_at() +{ + +} + +#[test] +fn record_set() +{ + +} diff --git a/src/tests/schema.rs b/src/tests/schema.rs new file mode 100644 index 0000000..c9228dc --- /dev/null +++ b/src/tests/schema.rs @@ -0,0 +1,8 @@ +use crate::*; + +#[test] +fn schema_initialize() +{ + let _data = Schema::new(); + +} diff --git a/src/tests/sequence.rs b/src/tests/sequence.rs new file mode 100644 index 0000000..56ccd02 --- /dev/null +++ b/src/tests/sequence.rs @@ -0,0 +1,26 @@ +use crate::*; + +#[test] +fn sequence_initialize() +{ + let value = Sequence::new(); + assert_eq!(0, value.size(), "Sequence::new() has length 0."); +} + +#[test] +fn sequence_set_get_raw() +{ + let mut value = Sequence::new(); + value.set_raw(vec![0, 1, 2, 3, 2, 1]); + assert_eq!(6, value.size(), "Sequence.set_raw([0,1,2,3,2,1]) has length 6."); + assert_eq!(vec![0,1,2,3,2,1], value.get_raw(), "Sequence.set_raw([0,1,2,3,2,1]) produces value [0,1,2,3,2,1]."); +} + +#[test] +fn sequence_set_get_str() +{ + let mut value = Sequence::new(); + value.set("hello"); + assert_eq!(5, value.size(), "Sequence.set(hello) has length 5."); + assert_eq!(String::from("hello"), value.get(), "Sequence.set(hello) produces value hello."); +} diff --git a/src/tests/sparse.rs b/src/tests/sparse.rs new file mode 100644 index 0000000..c93d128 --- /dev/null +++ b/src/tests/sparse.rs @@ -0,0 +1,8 @@ +use crate::*; + +#[test] +fn sparse_initialize() +{ + let data = Sparse::new(natural()); + assert_eq!(0, data.length(), "New list has length of 0."); +}