diff --git a/bindings/rust/src/lazy_reader.rs b/bindings/rust/src/lazy_reader.rs index ad8c68e..252ce59 100644 --- a/bindings/rust/src/lazy_reader.rs +++ b/bindings/rust/src/lazy_reader.rs @@ -23,7 +23,14 @@ pub enum Error { Overflow(String), Read(String), Verify(String), + Unknow(String), } +impl From for Error { + fn from(value: core::convert::Infallible) -> Self { + Self::Unknow(format!("conver failed: {:?}", value)) + } +} + pub trait Read { /** * try to read `buf.len()` bytes from data source with `offset`, then fill it in `buf`. @@ -470,10 +477,9 @@ impl_cursor_primitive!(i8); impl TryFrom for Vec { type Error = Error; fn try_from(cur: Cursor) -> Result { - let mut buf = Vec::::new(); - buf.resize(cur.size, 0); + let mut buf = vec![0u8; cur.size]; - let size = cur.read_at(buf.as_mut_slice())?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { return Err(Error::Read(format!( "TryFrom: size({}) != buf.len()({})", @@ -485,6 +491,24 @@ impl TryFrom for Vec { } } +impl TryFrom for [u8; N] { + type Error = Error; + fn try_from(cur: Cursor) -> Result { + let mut buf = [0u8; N]; + + let size = cur.read_at(&mut buf[..])?; + if size != N || size != cur.size { + return Err(Error::Read(format!( + "TryFrom: size({}) != buf.len()({})", + size, + buf.len() + ))); + } + + Ok(buf) + } +} + // it's an example about how to build a data source from memory impl Read for Vec { fn read(&self, buf: &mut [u8], offset: usize) -> Result { @@ -515,4 +539,10 @@ impl From> for Cursor { Cursor::new(mem.len(), Box::new(mem)) } } + +impl From<[u8; N]> for Cursor { + fn from(mem: [u8; N]) -> Self { + Cursor::new(mem.len(), Box::new(mem.to_vec())) + } +} // end of example diff --git a/examples/ci-tests/Cargo.lock b/examples/ci-tests/Cargo.lock index 71b5445..3d9b59e 100644 --- a/examples/ci-tests/Cargo.lock +++ b/examples/ci-tests/Cargo.lock @@ -106,12 +106,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - [[package]] name = "errno" version = "0.3.8" @@ -169,26 +163,20 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "indexmap" -version = "2.1.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "equivalent", + "autocfg", "hashbrown", ] -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - [[package]] name = "lazy_static" version = "1.4.0" @@ -201,6 +189,12 @@ version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -546,15 +540,14 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.30" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ "indexmap", - "itoa", "ryu", "serde", - "unsafe-libyaml", + "yaml-rust", ] [[package]] @@ -664,12 +657,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unsafe-libyaml" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" - [[package]] name = "version_check" version = "0.9.4" @@ -787,3 +774,12 @@ name = "windows_x86_64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/examples/ci-tests/Makefile b/examples/ci-tests/Makefile index e4246fa..f0eddbe 100644 --- a/examples/ci-tests/Makefile +++ b/examples/ci-tests/Makefile @@ -22,7 +22,7 @@ C_DEPS = ${MOL_DEPS} \ CC = gcc CXX = g++ -CFLAGS = -Wall -Werror +CFLAGS = -Wall -Werror -Wno-array-bounds clean: @cargo clean diff --git a/examples/ci-tests/c/simple-example.c b/examples/ci-tests/c/simple-example.c index b0927f9..aa683d7 100644 --- a/examples/ci-tests/c/simple-example.c +++ b/examples/ci-tests/c/simple-example.c @@ -138,7 +138,7 @@ void test_build_simple() { mol_seg_t uniona; { const uint8_t expected[] = { - ____, ____, ____, ____, + 0x02, ____, ____, ____, 0x12, }; MolBuilder_UnionA_init(&b); @@ -148,7 +148,7 @@ void test_build_simple() { } { const uint8_t expected[] = { - 0x03, ____, ____, ____, + 0x0b, ____, ____, ____, 0x03, ____, ____, ____, 0x12, 0x34, 0x56, }; diff --git a/examples/ci-tests/tests/simple.rs b/examples/ci-tests/tests/simple.rs index 020909e..514ab93 100644 --- a/examples/ci-tests/tests/simple.rs +++ b/examples/ci-tests/tests/simple.rs @@ -100,7 +100,7 @@ fn union_default() { test_default!( UnionA, s!("0x\ - 00000000\ + 02000000\ 00\ ") ); diff --git a/examples/lazy-reader-tests/build.rs b/examples/lazy-reader-tests/build.rs index 7a58446..a01260b 100644 --- a/examples/lazy-reader-tests/build.rs +++ b/examples/lazy-reader-tests/build.rs @@ -9,13 +9,20 @@ use std::{ fn compile_schema_rust(schema: &str) { let mut compiler = Compiler::new(); let out_dir = path::PathBuf::from(&env::var("OUT_DIR").unwrap_or_else(|_| ".".to_string())); + let mut file_path = out_dir.clone(); compiler .input_schema_file(schema) .generate_code(Language::Rust) .output_dir(out_dir) .run() .unwrap(); - + file_path.push("types.rs"); + Command::new("rustfmt") + .arg(>::as_ref(&file_path)) + .spawn() + .unwrap() + .wait() + .unwrap(); println!("cargo:rerun-if-changed={}", schema); } diff --git a/examples/lazy-reader-tests/src/lib.rs b/examples/lazy-reader-tests/src/lib.rs index 06f9d9b..86d396b 100644 --- a/examples/lazy-reader-tests/src/lib.rs +++ b/examples/lazy-reader-tests/src/lib.rs @@ -10,6 +10,7 @@ pub mod types_struct; pub mod types_table; pub mod types_vec; +use molecule::lazy_reader::Cursor; use molecule::prelude::{Builder, Entity}; use rand::{rngs::ThreadRng, thread_rng, Rng}; use std::fmt::Debug; @@ -144,9 +145,15 @@ impl From for TypesCheckErr { Overflow(v) => Self::Mol2Err(format!("Overflow({})", v)), Read(v) => Self::Mol2Err(format!("Read({})", v)), Verify(v) => Self::Mol2Err(format!("Verify({})", v)), + Unknow(v) => Self::Mol2Err(format!("Unknow({})", v)), } } } +impl From for TypesCheckErr { + fn from(value: std::convert::Infallible) -> Self { + Self::Mol2Err(format!("conver failed: {:?}", value)) + } +} pub enum TypesUnionA { Byte(TypesArray), @@ -203,14 +210,138 @@ impl TypesUnionA { // let item_id = d.item_id(); match self { - Self::Byte(v) => v.check(&d.as_byte()?), - Self::Word(v) => v.check2(&d.as_word()?.into()), - Self::StructA(v) => v.check(&d.as_struct_a()?), - Self::Bytes(v) => v.check(&d.as_bytes()?.try_into().unwrap()), - Self::Words(v) => v.check(&d.as_words()?.into()), - Self::Table0(v) => v.check(&d.as_table0()?), - Self::Table6(v) => v.check(&d.as_table6()?), - Self::Table6Opt(v) => v.check(&d.as_table6_opt()?), + Self::Byte(v) => match d { + types_api2::UnionA::Byte(v2) => v.check(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::Word(v) => match d { + types_api2::UnionA::Word(v2) => v.check2(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::StructA(v) => match d { + types_api2::UnionA::StructA(v2) => v.check(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::Bytes(v) => match d { + types_api2::UnionA::Bytes(v2) => { + v.check(&v2.clone().try_into()?) + } + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::Words(v) => match d { + types_api2::UnionA::Words(v2) => v.check(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::Table0(v) => match d { + types_api2::UnionA::Table0(v2) => v.check(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::Table6(v) => match d { + types_api2::UnionA::Table6(v2) => v.check(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::Table6Opt(v) => match d { + types_api2::UnionA::Table6Opt(v2) => v.check(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + } + } +} + +pub enum TypesUnionB { + Byte(TypesArray), // 2 + Word(TypesArrayWord), //4 +} +impl BaseTypes for TypesUnionB { + fn new_rng(rng: &mut ThreadRng, config: &TypesConfig) -> Self { + let v = if config.min_size { + 0 // Self::Byte + } else { + rng.gen_range(0..1) + }; + match v { + 0 => Self::Byte(TypesArray::new_rng(rng, config)), + 1 => Self::Word(TypesArrayWord::new_rng(rng, config)), + + _ => panic!("unknow error"), + } + } +} +impl Default for TypesUnionB { + fn default() -> Self { + Self::new_rng(&mut thread_rng(), &TypesConfig::default()) + } +} +impl TypesUnionB { + pub fn to_mol(&self) -> types_api::UnionB { + let t = match self { + Self::Byte(v) => types_api::UnionBUnion::Byte(v.to_mol()), + Self::Word(v) => types_api::UnionBUnion::Word(v.to_mol2()), + }; + types_api::UnionB::new_builder().set(t).build() + } + + pub fn check(&self, d: &types_api2::UnionB) -> ResCheckErr { + // let item_id = d.item_id(); + + match self { + Self::Byte(v) => match d { + types_api2::UnionB::Byte(v2) => v.check(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::Word(v) => match d { + types_api2::UnionB::Word(v2) => v.check2(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + } + } +} + +pub enum TypesUnionD { + Word(TypesArrayWord), //2 + Byte(TypesArray), // 4 +} +impl BaseTypes for TypesUnionD { + fn new_rng(rng: &mut ThreadRng, config: &TypesConfig) -> Self { + let v = if config.min_size { + 0 // Self::Byte + } else { + rng.gen_range(0..1) + }; + match v { + 0 => Self::Word(TypesArrayWord::new_rng(rng, config)), + 1 => Self::Byte(TypesArray::new_rng(rng, config)), + + _ => panic!("unknow error"), + } + } +} +impl Default for TypesUnionD { + fn default() -> Self { + Self::new_rng(&mut thread_rng(), &TypesConfig::default()) + } +} +impl TypesUnionD { + pub fn to_mol(&self) -> types_api::UnionD { + let t = match self { + Self::Word(v) => types_api::UnionDUnion::Word(v.to_mol2()), + Self::Byte(v) => types_api::UnionDUnion::Byte(v.to_mol()), + }; + types_api::UnionD::new_builder().set(t).build() + } + + pub fn check(&self, d: &types_api2::UnionD) -> ResCheckErr { + // let item_id = d.item_id(); + + match self { + Self::Word(v) => match d { + types_api2::UnionD::Word(v2) => v.check2(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + Self::Byte(v) => match d { + types_api2::UnionD::Byte(v2) => v.check(v2), + _ => Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, } } } diff --git a/examples/lazy-reader-tests/src/types_all_data.rs b/examples/lazy-reader-tests/src/types_all_data.rs index 1584b01..37e0ceb 100644 --- a/examples/lazy-reader-tests/src/types_all_data.rs +++ b/examples/lazy-reader-tests/src/types_all_data.rs @@ -102,6 +102,9 @@ pub struct TypesAll { f72: TypesUnionA, f73: TypesTableA, f74: TypesTableB, + + f75: TypesUnionB, + f76: TypesUnionD, } impl TypesAll { @@ -183,6 +186,8 @@ impl TypesAll { f72: TypesUnionA::new_rng(&mut rng, config), f73: TypesTableA::new_rng(&mut rng, config), f74: TypesTableB::new_rng(&mut rng, config), + f75: TypesUnionB::new_rng(&mut rng, config), + f76: TypesUnionD::new_rng(&mut rng, config), } } pub fn to_bytes(&self) -> Vec { @@ -268,6 +273,8 @@ impl TypesAll { .f72(self.f72.to_mol()) .f73(self.f73.to_mol()) .f74(self.f74.to_mol()) + .f75(self.f75.to_mol()) + .f76(self.f76.to_mol()) .build(); builder.as_reader().as_slice().to_vec() @@ -286,53 +293,53 @@ impl TypesAll { .check(&all_in_one.f0()?) .map_err(|f| f.to(format!("f0:{}", f.as_str())))?; self.f1 - .check(&all_in_one.f1()?.into()) + .check(&Cursor::try_from(all_in_one.f1()?)?.into()) .map_err(|f| f.to(format!("f1:{}", f.as_str())))?; self.f2 - .check(&all_in_one.f2()?.into()) + .check(&Cursor::try_from(all_in_one.f2()?)?.into()) .map_err(|f| f.to(format!("f2:{}", f.as_str())))?; self.f3 - .check(&all_in_one.f3()?.into()) + .check(&Cursor::try_from(all_in_one.f3()?)?.into()) .map_err(|f| f.to(format!("f3:{}", f.as_str())))?; self.f4 - .check(&all_in_one.f4()?.into()) + .check(&Cursor::try_from(all_in_one.f4()?)?.into()) .map_err(|f| f.to(format!("f74:{}", f.as_str())))?; self.f5 - .check(&all_in_one.f5()?.into()) + .check(&Cursor::try_from(all_in_one.f5()?)?.into()) .map_err(|f| f.to(format!("f5:{}", f.as_str())))?; self.f6 - .check(&all_in_one.f6()?.into()) + .check(&Cursor::try_from(all_in_one.f6()?)?.into()) .map_err(|f| f.to(format!("f6:{}", f.as_str())))?; self.f7 - .check(&all_in_one.f7()?.into()) + .check(&Cursor::try_from(all_in_one.f7()?)?.into()) .map_err(|f| f.to(format!("f7:{}", f.as_str())))?; self.f8 - .check(&all_in_one.f8()?.into()) + .check(&Cursor::try_from(all_in_one.f8()?)?.into()) .map_err(|f| f.to(format!("f8:{}", f.as_str())))?; self.f9 - .check(&all_in_one.f9()?.into()) + .check(&Cursor::try_from(all_in_one.f9()?)?.into()) .map_err(|f| f.to(format!("f9:{}", f.as_str())))?; self.f10 - .check(&all_in_one.f10()?.into()) + .check(&Cursor::try_from(all_in_one.f10()?)?.into()) .map_err(|f| f.to(format!("f10:{}", f.as_str())))?; self.f11 - .check(&all_in_one.f11()?.into()) + .check(&Cursor::try_from(all_in_one.f11()?)?.into()) .map_err(|f| f.to(format!("f11:{}", f.as_str())))?; self.f12 - .check(&all_in_one.f12()?.into()) + .check(&Cursor::try_from(all_in_one.f12()?)?.into()) .map_err(|f| f.to(format!("f12:{}", f.as_str())))?; self.f13 - .check(&all_in_one.f13()?.into()) + .check(&Cursor::try_from(all_in_one.f13()?)?.into()) .map_err(|f| f.to(format!("f13:{}", f.as_str())))?; self.f14 - .check(&all_in_one.f14()?.into()) + .check(&Cursor::try_from(all_in_one.f14()?)?.into()) .map_err(|f| f.to(format!("f14:{}", f.as_str())))?; self.f15 - .check(&all_in_one.f15()?.into()) + .check(&Cursor::try_from(all_in_one.f15()?)?.into()) .map_err(|f| f.to(format!("f15:{}", f.as_str())))?; self.f16 - .check2(&all_in_one.f16()?.into()) + .check2(&Cursor::try_from(all_in_one.f16()?)?.into()) .map_err(|f| f.to(format!("f16:{}", f.as_str())))?; self.f17 .check(&all_in_one.f17()?.into()) @@ -512,7 +519,12 @@ impl TypesAll { self.f74 .check(&all_in_one.f74()?) .map_err(|f| f.to(format!("f74:{}", f.as_str())))?; - + self.f75 + .check(&all_in_one.f75()?) + .map_err(|f| f.to(format!("f75:{}", f.as_str())))?; + self.f76 + .check(&all_in_one.f76()?) + .map_err(|f| f.to(format!("f76:{}", f.as_str())))?; types_api::AllInOneReader::verify(&data, true).expect("check data"); check_mol( @@ -925,26 +937,26 @@ fn test_union() { // success let buf = data.as_bytes().to_vec(); - types_api2::UnionA { - cursor: new_cursor(&buf), - } - .verify(true) - .unwrap(); + + types_api2::UnionA::try_from(new_cursor(&buf)) + .expect("new UnionA failed") + .verify(true) + .expect("verify unionA failed"); // Error item let mut buf = data.as_bytes().to_vec(); buf[0..4].copy_from_slice(&rng.gen_range(8u32..0xFFFFFFFEu32).to_le_bytes()); - types_api2::UnionA { - cursor: new_cursor(&buf), + let union_a = types_api2::UnionA::try_from(new_cursor(&buf)); + if union_a.is_ok() && union_a.unwrap().verify(true).is_ok() { + panic!("verify failedunionA failed"); } - .verify(true) - .unwrap_err(); - if item_id != 3 { + if item_id != 11 { + // exclude Bytes // Error length let mut buf = data.as_bytes().to_vec(); - if item_id != 4 { + if item_id != 0xFF000001 { buf.extend_from_slice(&rng.gen::().to_le_bytes()); } else { buf.extend_from_slice({ @@ -956,11 +968,10 @@ fn test_union() { }) } - types_api2::UnionA { - cursor: new_cursor(&buf), + let union_a = types_api2::UnionA::try_from(new_cursor(&buf)); + if union_a.is_ok() && union_a.unwrap().verify(true).is_ok() { + panic!("verify failedunionA failed"); } - .verify(true) - .unwrap_err(); } } @@ -972,6 +983,7 @@ fn test_union() { test_union_item(TypesUnionA::Table0(TypesTable0::default())); test_union_item(TypesUnionA::Table6(TypesTable6::default())); test_union_item(TypesUnionA::Table6Opt(TypesOption::default())); + test_union_item(TypesUnionA::Table6Opt(TypesOption::new_none())); } #[test] diff --git a/examples/lazy-reader-tests/src/types_api2_mol2.rs b/examples/lazy-reader-tests/src/types_api2_mol2.rs index 157f893..a0f4ae2 100644 --- a/examples/lazy-reader-tests/src/types_api2_mol2.rs +++ b/examples/lazy-reader-tests/src/types_api2_mol2.rs @@ -212,7 +212,7 @@ impl Mol2Vec for Word2 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Word3 { @@ -221,7 +221,7 @@ impl Mol2Vec for Word3 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Word4 { @@ -230,7 +230,7 @@ impl Mol2Vec for Word4 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Word5 { @@ -239,7 +239,7 @@ impl Mol2Vec for Word5 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Word6 { @@ -248,7 +248,7 @@ impl Mol2Vec for Word6 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Word7 { @@ -257,7 +257,7 @@ impl Mol2Vec for Word7 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Word8 { @@ -266,7 +266,7 @@ impl Mol2Vec for Word8 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Byte3x3 { @@ -275,7 +275,7 @@ impl Mol2Vec for Byte3x3 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Byte5x3 { @@ -284,7 +284,7 @@ impl Mol2Vec for Byte5x3 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Byte7x3 { @@ -293,7 +293,7 @@ impl Mol2Vec for Byte7x3 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Byte9x3 { @@ -302,7 +302,7 @@ impl Mol2Vec for Byte9x3 { Ok(self.len()) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Words { @@ -311,7 +311,7 @@ impl Mol2Vec for Words { Ok(self.len()?) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Byte3Vec { @@ -320,7 +320,7 @@ impl Mol2Vec for Byte3Vec { Ok(self.len()?) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for Byte7Vec { @@ -329,7 +329,7 @@ impl Mol2Vec for Byte7Vec { Ok(self.len()?) } fn mol_get(&self, index: usize) -> Result { - Ok(Self::RetType::from(self.get(index)?)) + Ok(Self::RetType::from(Cursor::try_from(self.get(index)?)?)) } } impl Mol2Vec for BytesVec { diff --git a/examples/lazy-reader-tests/src/types_array.rs b/examples/lazy-reader-tests/src/types_array.rs index 75b64bf..e4fb37f 100644 --- a/examples/lazy-reader-tests/src/types_array.rs +++ b/examples/lazy-reader-tests/src/types_array.rs @@ -1,5 +1,6 @@ use super::{BaseTypes, ResCheckErr, TypesCheckErr, TypesConfig}; use crate::{types_api, types_api2}; +use molecule::lazy_reader::Cursor; use molecule::prelude::{Builder, Byte, Entity}; use rand::{rngs::ThreadRng, thread_rng}; @@ -219,7 +220,7 @@ impl TypesArray { } pub fn check(&self, d: &types_api2::Word2) -> ResCheckErr { for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -233,7 +234,7 @@ impl TypesArray { pub fn check(&self, d: &types_api2::Word3) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -247,7 +248,7 @@ impl TypesArray { pub fn check(&self, d: &types_api2::Word4) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -261,7 +262,7 @@ impl TypesArray { pub fn check(&self, d: &types_api2::Word5) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -275,7 +276,7 @@ impl TypesArray { pub fn check(&self, d: &types_api2::Word6) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -289,7 +290,7 @@ impl TypesArray { pub fn check(&self, d: &types_api2::Word7) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -303,7 +304,7 @@ impl TypesArray { pub fn check(&self, d: &types_api2::Word8) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -317,7 +318,7 @@ impl TypesArray, 3> { pub fn check(&self, d: &types_api2::Byte3x3) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -332,7 +333,7 @@ impl TypesArray, 3> { pub fn check(&self, d: &types_api2::Byte5x3) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -346,7 +347,7 @@ impl TypesArray, 3> { pub fn check(&self, d: &types_api2::Byte7x3) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -360,7 +361,7 @@ impl TypesArray, 3> { pub fn check(&self, d: &types_api2::Byte9x3) -> ResCheckErr { TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } diff --git a/examples/lazy-reader-tests/src/types_moleculec_check.rs b/examples/lazy-reader-tests/src/types_moleculec_check.rs index 4e052f9..78146e4 100644 --- a/examples/lazy-reader-tests/src/types_moleculec_check.rs +++ b/examples/lazy-reader-tests/src/types_moleculec_check.rs @@ -4,23 +4,23 @@ use molecule::prelude::Byte; pub fn check_mol(d1: &types_api::AllInOne, d2: &types_api2::AllInOne) -> ResCheckErr { check_f0(&d1.f0(), &d2.f0()?.into())?; - check_f1(&d1.f1(), &d2.f1()?.into())?; - check_f2(&d1.f2(), &d2.f2()?.into())?; - check_f3(&d1.f3(), &d2.f3()?.into())?; - check_f4(&d1.f4(), &d2.f4()?.into())?; - check_f5(&d1.f5(), &d2.f5()?.into())?; - check_f6(&d1.f6(), &d2.f6()?.into())?; - check_f7(&d1.f7(), &d2.f7()?.into())?; - check_f8(&d1.f8(), &d2.f8()?.into())?; - check_f9(&d1.f9(), &d2.f9()?.into())?; - check_f10(&d1.f10(), &d2.f10()?.into())?; - check_f11(&d1.f11(), &d2.f11()?.into())?; - check_f12(&d1.f12(), &d2.f12()?.into())?; - check_f13(&d1.f13(), &d2.f13()?.into())?; - check_f14(&d1.f14(), &d2.f14()?.into())?; - check_f15(&d1.f15(), &d2.f15()?.into())?; - - check_f16(&d1.f16(), &d2.f16()?.into())?; + check_f1(&d1.f1(), &Cursor::try_from(d2.f1()?)?.into())?; + check_f2(&d1.f2(), &Cursor::try_from(d2.f2()?)?.into())?; + check_f3(&d1.f3(), &Cursor::try_from(d2.f3()?)?.into())?; + check_f4(&d1.f4(), &Cursor::try_from(d2.f4()?)?.into())?; + check_f5(&d1.f5(), &Cursor::try_from(d2.f5()?)?.into())?; + check_f6(&d1.f6(), &Cursor::try_from(d2.f6()?)?.into())?; + check_f7(&d1.f7(), &Cursor::try_from(d2.f7()?)?.into())?; + check_f8(&d1.f8(), &Cursor::try_from(d2.f8()?)?.into())?; + check_f9(&d1.f9(), &Cursor::try_from(d2.f9()?)?.into())?; + check_f10(&d1.f10(), &Cursor::try_from(d2.f10()?)?.into())?; + check_f11(&d1.f11(), &Cursor::try_from(d2.f11()?)?.into())?; + check_f12(&d1.f12(), &Cursor::try_from(d2.f12()?)?.into())?; + check_f13(&d1.f13(), &Cursor::try_from(d2.f13()?)?.into())?; + check_f14(&d1.f14(), &Cursor::try_from(d2.f14()?)?.into())?; + check_f15(&d1.f15(), &Cursor::try_from(d2.f15()?)?.into())?; + + check_f16(&d1.f16(), &Cursor::try_from(d2.f16()?)?.into())?; check_f17(&d1.f17(), &d2.f17()?.into())?; check_f18(&d1.f18(), &d2.f18()?.into())?; check_f19(&d1.f19(), &d2.f19()?.into())?; @@ -67,7 +67,10 @@ pub fn check_mol(d1: &types_api::AllInOne, d2: &types_api2::AllInOne) -> ResChec check_f56(&d1.f56(), &d2.f56()?.into())?; check_f57(&d1.f57().to_opt(), &d2.f57()?)?; - check_f58(&d1.f58().to_opt(), &d2.f58()?.map(|f| f.into()))?; + check_f58( + &d1.f58().to_opt(), + &d2.f58()?.map(|f| Cursor::try_from(f).unwrap().into()), + )?; check_f59(&d1.f59().to_opt(), &d2.f59()?)?; check_f60(&d1.f60().to_opt(), &d2.f60()?)?; check_f61( @@ -231,74 +234,74 @@ pub fn check_f27(d1: &types_api::Byte9x3, d2: &types_api2::Byte9x3) -> ResCheckE pub fn check_f28(d1: &types_api::StructA, d2: &types_api2::StructA) -> ResCheckErr { check_f0(&d1.f1(), &d2.f1()?.into())?; check_f0(&d1.f2(), &d2.f2()?.into())?; - check_f1(&d1.f3(), &d2.f3()?.into())?; - check_f1(&d1.f4(), &d2.f4()?.into())?; + check_f1(&d1.f3(), &Cursor::try_from(d2.f3()?)?.into())?; + check_f1(&d1.f4(), &Cursor::try_from(d2.f4()?)?.into())?; Ok(()) } pub fn check_f29(d1: &types_api::StructB, d2: &types_api2::StructB) -> ResCheckErr { check_f0(&d1.f1(), &d2.f1()?.into())?; check_f0(&d1.f2(), &d2.f2()?.into())?; - check_f1(&d1.f3(), &d2.f3()?.into())?; - check_f2(&d1.f4(), &d2.f4()?.into())?; + check_f1(&d1.f3(), &Cursor::try_from(d2.f3()?)?.into())?; + check_f2(&d1.f4(), &Cursor::try_from(d2.f4()?)?.into())?; Ok(()) } pub fn check_f30(d1: &types_api::StructC, d2: &types_api2::StructC) -> ResCheckErr { check_f0(&d1.f1(), &d2.f1()?.into())?; check_f0(&d1.f2(), &d2.f2()?.into())?; - check_f1(&d1.f3(), &d2.f3()?.into())?; - check_f3(&d1.f4(), &d2.f4()?.into())?; + check_f1(&d1.f3(), &Cursor::try_from(d2.f3()?)?.into())?; + check_f3(&d1.f4(), &Cursor::try_from(d2.f4()?)?.into())?; Ok(()) } pub fn check_f31(d1: &types_api::StructD, d2: &types_api2::StructD) -> ResCheckErr { check_f0(&d1.f1(), &d2.f1()?.into())?; check_f0(&d1.f2(), &d2.f2()?.into())?; - check_f1(&d1.f3(), &d2.f3()?.into())?; - check_f4(&d1.f4(), &d2.f4()?.into())?; + check_f1(&d1.f3(), &Cursor::try_from(d2.f3()?)?.into())?; + check_f4(&d1.f4(), &Cursor::try_from(d2.f4()?)?.into())?; Ok(()) } pub fn check_f32(d1: &types_api::StructE, d2: &types_api2::StructE) -> ResCheckErr { check_f0(&d1.f1(), &d2.f1()?.into())?; - check_f1(&d1.f2(), &d2.f2()?.into())?; + check_f1(&d1.f2(), &Cursor::try_from(d2.f2()?)?.into())?; check_f0(&d1.f3(), &d2.f3()?.into())?; - check_f1(&d1.f4(), &d2.f4()?.into())?; + check_f1(&d1.f4(), &Cursor::try_from(d2.f4()?)?.into())?; Ok(()) } pub fn check_f33(d1: &types_api::StructF, d2: &types_api2::StructF) -> ResCheckErr { check_f0(&d1.f1(), &d2.f1()?.into())?; - check_f2(&d1.f2(), &d2.f2()?.into())?; + check_f2(&d1.f2(), &Cursor::try_from(d2.f2()?)?.into())?; check_f0(&d1.f3(), &d2.f3()?.into())?; Ok(()) } pub fn check_f34(d1: &types_api::StructG, d2: &types_api2::StructG) -> ResCheckErr { - check_f2(&d1.f1(), &d2.f1()?.into())?; + check_f2(&d1.f1(), &Cursor::try_from(d2.f1()?)?.into())?; check_f0(&d1.f2(), &d2.f2()?.into())?; - check_f1(&d1.f3(), &d2.f3()?.into())?; + check_f1(&d1.f3(), &Cursor::try_from(d2.f3()?)?.into())?; check_f17(&d1.f4(), &d2.f4()?.into())?; Ok(()) } pub fn check_f35(d1: &types_api::StructH, d2: &types_api2::StructH) -> ResCheckErr { - check_f2(&d1.f1(), &d2.f1()?.into())?; + check_f2(&d1.f1(), &Cursor::try_from(d2.f1()?)?.into())?; check_f0(&d1.f2(), &d2.f2()?.into())?; - check_f1(&d1.f3(), &d2.f3()?.into())?; - check_f3(&d1.f4(), &d2.f4()?.into())?; + check_f1(&d1.f3(), &Cursor::try_from(d2.f3()?)?.into())?; + check_f3(&d1.f4(), &Cursor::try_from(d2.f4()?)?.into())?; Ok(()) } pub fn check_f36(d1: &types_api::StructI, d2: &types_api2::StructI) -> ResCheckErr { - check_f2(&d1.f1(), &d2.f1()?.into())?; + check_f2(&d1.f1(), &Cursor::try_from(d2.f1()?)?.into())?; check_f0(&d1.f2(), &d2.f2()?.into())?; Ok(()) } pub fn check_f37(d1: &types_api::StructJ, d2: &types_api2::StructJ) -> ResCheckErr { - check_f5(&d1.f1(), &d2.f1()?.into())?; + check_f5(&d1.f1(), &Cursor::try_from(d2.f1()?)?.into())?; check_f0(&d1.f2(), &d2.f2()?.into())?; Ok(()) @@ -631,7 +634,7 @@ pub fn check_f69(d1: &types_api::WordOptVec, d2: &types_api2::WordOptVec) -> Res TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { let dd1 = d1.mol_get(i)?.to_opt(); - let dd2 = d2.get(i)?.map(|f| f.into()); + let dd2 = d2.get(i)?.map(|f| Cursor::try_from(f).unwrap().into()); check_f58(&dd1, &dd2)?; } Ok(()) @@ -656,38 +659,38 @@ pub fn check_f71(d1: &types_api::BytesOptVec, d2: &types_api2::BytesOptVec) -> R } pub fn check_f72(d1: &types_api::UnionA, d2: &types_api2::UnionA) -> ResCheckErr { match d1.to_enum() { - types_api::UnionAUnion::Byte(v) => { - let v2 = d2.as_byte()?; - TypesCheckErr::check_1_data(&v, &v2.into())?; - } - types_api::UnionAUnion::Word(v) => { - let v2 = d2.as_word()?; - check_f16(&v, &v2.into())?; - } - types_api::UnionAUnion::StructA(v) => { - let v2 = d2.as_struct_a()?; - check_f28(&v, &v2)?; - } - types_api::UnionAUnion::Bytes(v) => { - let v2 = d2.as_bytes()?; - check_f41(&v, &v2.try_into().unwrap())?; - } - types_api::UnionAUnion::Words(v) => { - let v2 = d2.as_words()?; - check_f42(&v, &v2)?; - } - types_api::UnionAUnion::Table0(v) => { - let v2 = d2.as_table0()?; - check_f50(&v, &v2)?; - } - types_api::UnionAUnion::Table6(v) => { - let v2 = d2.as_table6()?; - check_f56(&v, &v2)?; - } - types_api::UnionAUnion::Table6Opt(v) => { - let v2 = d2.as_table6_opt()?; - check_f66(&v.to_opt(), &v2)?; - } + types_api::UnionAUnion::Byte(v) => match d2 { + types_api2::UnionA::Byte(v2) => TypesCheckErr::check_1_data(&v, &v2.clone().into())?, + _ => return Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + types_api::UnionAUnion::Word(v) => match d2 { + types_api2::UnionA::Word(v2) => check_f16(&v, v2)?, + _ => return Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + types_api::UnionAUnion::StructA(v) => match d2 { + types_api2::UnionA::StructA(v2) => check_f28(&v, &v2)?, + _ => return Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + types_api::UnionAUnion::Bytes(v) => match d2 { + types_api2::UnionA::Bytes(v2) => check_f41(&v, &v2)?, + _ => return Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + types_api::UnionAUnion::Words(v) => match d2 { + types_api2::UnionA::Words(v2) => check_f42(&v, &v2)?, + _ => return Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + types_api::UnionAUnion::Table0(v) => match d2 { + types_api2::UnionA::Table0(v2) => check_f50(&v, v2)?, + _ => return Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + types_api::UnionAUnion::Table6(v) => match d2 { + types_api2::UnionA::Table6(v2) => check_f56(&v, v2)?, + _ => return Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, + types_api::UnionAUnion::Table6Opt(v) => match d2 { + types_api2::UnionA::Table6Opt(v2) => check_f66(&v.to_opt(), v2)?, + _ => return Err(TypesCheckErr::Data(format!("check union type is failed"))), + }, }; Ok(()) diff --git a/examples/lazy-reader-tests/src/types_option.rs b/examples/lazy-reader-tests/src/types_option.rs index ae8e4b9..c715c3b 100644 --- a/examples/lazy-reader-tests/src/types_option.rs +++ b/examples/lazy-reader-tests/src/types_option.rs @@ -36,6 +36,12 @@ impl Default for TypesOption { } } +impl TypesOption { + pub fn new_none() -> Self { + Self { d: None } + } +} + impl TypesOption { pub fn to_mol(&self) -> types_api::ByteOpt { types_api::ByteOpt::new_builder() diff --git a/examples/lazy-reader-tests/src/types_struct.rs b/examples/lazy-reader-tests/src/types_struct.rs index 918c38a..16efa2a 100644 --- a/examples/lazy-reader-tests/src/types_struct.rs +++ b/examples/lazy-reader-tests/src/types_struct.rs @@ -53,8 +53,8 @@ impl TypesStructA { pub fn check(&self, d: &types_api2::StructA) -> ResCheckErr { self.f1.check(&d.f1()?.into())?; self.f2.check(&d.f2()?.into())?; - self.f3.check(&d.f3()?.into())?; - self.f4.check(&d.f4()?.into())?; + self.f3.check(&Cursor::try_from(d.f3()?)?.into())?; + self.f4.check(&Cursor::try_from(d.f4()?)?.into())?; Ok(()) } } @@ -72,8 +72,8 @@ impl TypesStructB { pub fn check(&self, d: &types_api2::StructB) -> ResCheckErr { self.f1.check(&d.f1()?.into())?; self.f2.check(&d.f2()?.into())?; - self.f3.check(&d.f3()?.into())?; - self.f4.check(&d.f4()?.into())?; + self.f3.check(&Cursor::try_from(d.f3()?)?.into())?; + self.f4.check(&Cursor::try_from(d.f4()?)?.into())?; Ok(()) } } @@ -92,8 +92,8 @@ impl TypesStructC { pub fn check(&self, d: &types_api2::StructC) -> ResCheckErr { self.f1.check(&d.f1()?.into())?; self.f2.check(&d.f2()?.into())?; - self.f3.check(&d.f3()?.into())?; - self.f4.check(&d.f4()?.into())?; + self.f3.check(&Cursor::try_from(d.f3()?)?.into())?; + self.f4.check(&Cursor::try_from(d.f4()?)?.into())?; Ok(()) } } @@ -112,8 +112,8 @@ impl TypesStructD { pub fn check(&self, d: &types_api2::StructD) -> ResCheckErr { self.f1.check(&d.f1()?.into())?; self.f2.check(&d.f2()?.into())?; - self.f3.check(&d.f3()?.into())?; - self.f4.check(&d.f4()?.into())?; + self.f3.check(&Cursor::try_from(d.f3()?)?.into())?; + self.f4.check(&Cursor::try_from(d.f4()?)?.into())?; Ok(()) } } @@ -131,9 +131,9 @@ impl TypesStructE { } pub fn check(&self, d: &types_api2::StructE) -> ResCheckErr { self.f1.check(&d.f1()?.into())?; - self.f2.check(&d.f2()?.into())?; + self.f2.check(&Cursor::try_from(d.f2()?)?.into())?; self.f3.check(&d.f3()?.into())?; - self.f4.check(&d.f4()?.into())?; + self.f4.check(&Cursor::try_from(d.f4()?)?.into())?; Ok(()) } } @@ -150,7 +150,7 @@ impl TypesStructF { } pub fn check(&self, d: &types_api2::StructF) -> ResCheckErr { self.f1.check(&d.f1()?.into())?; - self.f2.check(&d.f2()?.into())?; + self.f2.check(&Cursor::try_from(d.f2()?)?.into())?; self.f3.check(&d.f3()?.into())?; Ok(()) } @@ -172,9 +172,9 @@ impl TypesStructG { .build() } pub fn check(&self, d: &types_api2::StructG) -> ResCheckErr { - self.f1.check(&d.f1()?.into())?; + self.f1.check(&Cursor::try_from(d.f1()?)?.into())?; self.f2.check(&d.f2()?.into())?; - self.f3.check(&d.f3()?.into())?; + self.f3.check(&Cursor::try_from(d.f3()?)?.into())?; self.f4.check(&d.f4()?.into())?; Ok(()) } @@ -192,10 +192,10 @@ impl TypesStructH { .build() } pub fn check(&self, d: &types_api2::StructH) -> ResCheckErr { - self.f1.check(&d.f1()?.into())?; + self.f1.check(&Cursor::try_from(d.f1()?)?.into())?; self.f2.check(&d.f2()?.into())?; - self.f3.check(&d.f3()?.into())?; - self.f4.check(&d.f4()?.into())?; + self.f3.check(&Cursor::try_from(d.f3()?)?.into())?; + self.f4.check(&Cursor::try_from(d.f4()?)?.into())?; Ok(()) } } @@ -210,7 +210,7 @@ impl TypesStructI { .build() } pub fn check(&self, d: &types_api2::StructI) -> ResCheckErr { - self.f1.check(&d.f1()?.into())?; + self.f1.check(&Cursor::try_from(d.f1()?)?.into())?; self.f2.check(&d.f2()?.into())?; Ok(()) } @@ -226,7 +226,7 @@ impl TypesStructJ { .build() } pub fn check(&self, d: &types_api2::StructJ) -> ResCheckErr { - self.f1.check(&d.f1()?.into())?; + self.f1.check(&Cursor::try_from(d.f1()?)?.into())?; self.f2.check(&d.f2()?.into())?; Ok(()) } diff --git a/examples/lazy-reader-tests/src/types_vec.rs b/examples/lazy-reader-tests/src/types_vec.rs index 7789c22..8fec5b0 100644 --- a/examples/lazy-reader-tests/src/types_vec.rs +++ b/examples/lazy-reader-tests/src/types_vec.rs @@ -1,5 +1,6 @@ use super::*; use crate::{types_api, types_api2}; +use molecule::lazy_reader::Cursor; use molecule::prelude::{Builder, Entity}; use rand::{rngs::ThreadRng, thread_rng, Rng}; @@ -50,7 +51,7 @@ impl TypesVec { pub fn check(&self, d: &types_api2::Words) -> ResCheckErr { TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -64,7 +65,7 @@ impl TypesVec> { pub fn check(&self, d: &types_api2::Byte3Vec) -> ResCheckErr { TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -78,7 +79,7 @@ impl TypesVec> { pub fn check(&self, d: &types_api2::Byte7Vec) -> ResCheckErr { TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check(&Cursor::try_from(d.get(i)?)?.into())?; } Ok(()) } @@ -185,7 +186,13 @@ impl TypesVec> { pub fn check(&self, d: &types_api2::WordOptVec) -> ResCheckErr { TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { - self.d[i].check(&d.get(i)?.into())?; + self.d[i].check( + &match d.get(i)? { + Some(v) => Some(Cursor::try_from(v)?), + None => None, + } + .into(), + )?; } Ok(()) } diff --git a/test/schemas/types.mol b/test/schemas/types.mol index 5578a32..ed568b2 100644 --- a/test/schemas/types.mol +++ b/test/schemas/types.mol @@ -167,14 +167,14 @@ vector WordsOptVec ; vector BytesOptVec ; union UnionA { - byte, - Word, - StructA, - Bytes, - Words, - Table0, - Table6, - Table6Opt, + byte : 2, + Word : 3, + StructA : 7, + Bytes : 11, + Words : 4278190081, + Table0 : 4278190082, + Table6 : 4278190083, + Table6Opt : 4278190084, } union UnionB { @@ -299,4 +299,6 @@ table AllInOne { f72: UnionA, f73: TableA, f74: TableB, + f75: UnionB, + f76: UnionD, } diff --git a/test/vectors/default.yaml b/test/vectors/default.yaml index 3e3435b..5266376 100644 --- a/test/vectors/default.yaml +++ b/test/vectors/default.yaml @@ -218,7 +218,7 @@ 08000000\ 00\ \ - 00000000\ + 02000000\ 00\ \ 00" @@ -263,7 +263,7 @@ # - name: UnionA - expected: "0x00000000//00" + expected: "0x02000000//00" - name: UnionB expected: "0x02000000//00" diff --git a/test/vectors/simple.yaml b/test/vectors/simple.yaml index 6dca236..0cc441f 100644 --- a/test/vectors/simple.yaml +++ b/test/vectors/simple.yaml @@ -316,7 +316,7 @@ 01000000//00\ 02000000//00/11" f6: "0x00000000" - f7: "0x03000000//00000000" + f7: "0x0b000000//00000000" f8: "0x99" expected: "0x67000000//\ 24000000_28000000_2e000000_32000000_\ @@ -336,7 +336,7 @@ \ 00000000\ \ - 03000000\ + 0b000000\ 00000000\ \ 99" @@ -436,37 +436,37 @@ item: type: byte data: "0x00" - expected: "0x00000000//00" + expected: "0x02000000//00" - name: UnionA item: type: Word data: "0x0000" - expected: "0x01000000//0000" + expected: "0x03000000//0000" - name: UnionA item: type: StructA data: "0x00/00/0000/0000" - expected: "0x02000000//00/00/0000/0000" + expected: "0x07000000//00/00/0000/0000" - name: UnionA item: type: Bytes data: "0x00000000" - expected: "0x03000000//00000000" + expected: "0x0b000000//00000000" - name: UnionA item: type: Words data: "0x00000000" - expected: "0x04000000//00000000" + expected: "0x010000ff//00000000" - name: UnionA item: type: Table0 data: "0x04000000" - expected: "0x05000000//04000000" + expected: "0x020000ff//04000000" - name: UnionA item: @@ -482,7 +482,7 @@ 00000000_0000\ 00000000\ 04000000" - expected: "0x06000000//\ + expected: "0x030000ff//\ 5a000000//\ 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ 00/00000000/00000000_0000/00000000/04000000/\ @@ -499,7 +499,7 @@ item: type: Table6Opt data: "0x" - expected: "0x07000000" + expected: "0x040000ff" - name: UnionA item: @@ -515,7 +515,7 @@ 00000000_0000\ 00000000\ 04000000" - expected: "0x07000000//\ + expected: "0x040000ff//\ 5a000000//\ 1c000000_1d000000_21000000_27000000_2b000000_2f000000//\ 00/00000000/00000000_0000/00000000/04000000/\ diff --git a/tools/codegen/src/generator/languages/rust_lazy_reader/generator.rs b/tools/codegen/src/generator/languages/rust_lazy_reader/generator.rs index fa05e3c..2e96c0e 100644 --- a/tools/codegen/src/generator/languages/rust_lazy_reader/generator.rs +++ b/tools/codegen/src/generator/languages/rust_lazy_reader/generator.rs @@ -1,95 +1,207 @@ -use super::{ident_new, LazyReaderGenerator}; +use super::{ident_new, ident_new_camel, LazyReaderGenerator}; use crate::ast::{self, HasName, *}; -use case::CaseExt; use proc_macro2::{Literal, TokenStream}; use quote::quote; use std::io; +impl ast::Union { + fn get_item_name(typ: &TopDecl) -> TokenStream { + let item_name = ident_new_camel(typ.name()); + let item_type_name = Self::get_type_name(typ); + + quote! { + #item_name(#item_type_name), + } + } + + fn get_type_name(typ: &TopDecl) -> TokenStream { + match typ { + TopDecl::Primitive(v) => { + let name = ident_new(match v.name().to_lowercase().as_str() { + "byte" => "u8", + "uint8" => "u8", + "int8" => "i8", + "uint16" => "u16", + "int16" => "i16", + "uint32" => "u32", + "int32" => "i32", + "uint64" => "u64", + "int64" => "i64", + _ => { + panic!("unknow type: {}", v.name()) + } + }); + quote!(#name) + } + TopDecl::Option_(o) => { + let name = Self::get_type_name(o.item().typ()); + quote!(Option<#name>) + } + TopDecl::FixVec(v) => { + if let TopDecl::Primitive(_) = v.item().typ().as_ref() { + quote!(Cursor) + } else { + let name = ident_new_camel(typ.name()); + quote!(#name) + } + } + _ => { + let name = ident_new_camel(typ.name()); + quote!(#name) + } + } + } +} + impl LazyReaderGenerator for ast::Union { fn gen_rust(&self, output: &mut W) -> io::Result<()> { let name = ident_new(self.name()); - let q = quote! { - pub struct #name { - pub cursor: Cursor, + // generate enum: + let q = self.items().iter().map(|item| { + let item_name = Self::get_item_name(item.typ().as_ref()); + quote! { + #item_name } - - impl From for #name { - fn from(cursor: Cursor) -> Self { - Self { cursor } + }); + writeln!( + output, + "{}", + quote! { + pub enum #name { + #( #q )* } } + )?; - impl #name { - pub fn item_id(&self) -> Result { - let item = self.cursor.union_unpack()?; - Ok(item.item_id) + // generate enum try_from + let q = self.items().iter().map(|item| { + let item_id = item.id(); + let item_name_str = item.typ().name(); + let item_name = ident_new_camel(item_name_str); + let item_type = Self::get_type_name(item.typ()); + + let q = match item.typ().as_ref() { + TopDecl::Primitive(a) => match a.name().to_lowercase().as_str() { + "byte" | "uint8" | "int8" | "uint16" | "int16" | "uint32" | "int32" + | "uint64" | "int64" => { + quote! {{ + cur.verify_fixed_size(core::mem::size_of::<#item_type>())?; + cur.try_into()? + }} + } + _ => { + quote!(cur.into()) + } + }, + TopDecl::Option_(o) => { + let item_name = ident_new_camel(o.item().typ().name()); + quote! {{ + if cur.option_is_none() { + None + } else { + Some(#item_name::from(cur)) + } + }} } - } - }; - writeln!(output, "{}", q)?; + TopDecl::FixVec(v) => { + if let TopDecl::Primitive(_) = v.item().typ().as_ref() { + quote! {{ + if cur.fixvec_length()? != cur.size - NUMBER_SIZE { + return Err(Error::TotalSize(format!( + "total_size: {} != {}", + cur.fixvec_length()?, + cur.size + ))); + } - for (item_index, item) in self.items().iter().enumerate() { - let item_type_name = item.typ().name(); - let item_type_name = ident_new(&format!("as_{}", item_type_name.to_snake())); - let (transformed_name, tc) = get_rust_type_category(item.typ()); - let convert_code = tc.gen_convert_code(); - let q = quote! { - impl #name { - pub fn #item_type_name(&self) -> Result<#transformed_name, Error> { - let item = self.cursor.union_unpack()?; - if item.item_id != #item_index { - return Err(Error::Header(format!("invalid item type id in union: {}", item.item_id))); + cur.add_offset(NUMBER_SIZE)?; + cur.sub_size(NUMBER_SIZE)?; + cur + }} + } else { + quote! { + cur.into() } - let cur = item.cursor.clone(); - #convert_code + } + } + _ => { + quote! { + cur.into() } } }; - writeln!(output, "{}", q)?; - } - - let verify_items = self.items().iter().enumerate().map(|(_i, item)| { - let item_id = item.id(); - let item_type_name = item.typ().name(); - let item_type_name = ident_new(&format!("as_{}", item_type_name.to_snake())); - let typ = item.typ().as_ref(); + quote! { + #item_id => { + Ok(Self::#item_name(#q)) + } + } + }); + let q = quote! { + impl TryFrom for #name { + type Error = Error; + fn try_from(cur: Cursor) -> Result { + let item = cur.union_unpack()?; + + let mut cur = cur; + cur.add_offset(NUMBER_SIZE)?; + cur.sub_size(NUMBER_SIZE)?; + + match item.item_id { + #( #q )* + _ => Err(Error::UnknownItem(format!("unknow item id: {}", item.item_id))) + } + } + } + }; + writeln!(output, "{}", q)?; - let func = match typ { - TopDecl::Primitive(v) => { - let fixed_size = v.size() + molecule::NUMBER_SIZE; - quote!(self.cursor.verify_fixed_size(#fixed_size)?;) + // generate verify + let verify_items = self.items().iter().enumerate().map(|(_i, item)| { + let item_name = ident_new_camel(item.typ().name()); + match item.typ().as_ref() { + TopDecl::Primitive(_) => { + quote!( Self::#item_name(_v) => Ok(()), ) + } + TopDecl::Option_(_) => { + quote! { + Self::#item_name(v) => { + if v.is_some() { + v.as_ref().unwrap().verify(compatible)?; + } + Ok(()) + }, + } } TopDecl::FixVec(v) => { - let item_size = v.item_size(); - if item_size > 1 { - quote!( - self.#item_type_name()?.verify(compatible)?; - ) + if let TopDecl::Primitive(_) = v.item().typ().as_ref() { + quote! { + Self::#item_name(_v) => Ok(()), + } } else { - quote!() + quote! { + Self::#item_name(v) => { + v.verify(compatible)?; + Ok(()) + }, + } } } - _ => verify_typ(typ, quote!(self.#item_type_name()?)), - }; - quote!( - #item_id => { - #func; - Ok(()) - } - ) + _ => quote! { + Self::#item_name(v) => { + v.verify(compatible)?; + Ok(()) + }, + }, + } }); let q = quote! { impl #name { pub fn verify(&self, compatible: bool) -> Result<(), Error> { - let item_id = self.item_id()?; - match item_id { + match self { #( #verify_items )* - _ => { - Err(Error::UnknownItem(format!("unknow item id: {}", item_id))) - } } } } @@ -492,6 +604,7 @@ enum TypeCategory { // 2nd: is nested type is FixVec or not // 3rd: has From Option(u32, bool, bool), + Union, } impl TypeCategory { @@ -503,7 +616,7 @@ impl TypeCategory { } pub fn gen_convert_code(&self) -> TokenStream { match self { - &TypeCategory::Option(level, flag, has_from) => { + &TypeCategory::Option(level, flag, _has_from) => { if level == 1 { if flag { quote! { @@ -514,14 +627,15 @@ impl TypeCategory { Ok(Some(cur.into())) } } - } else if has_from { - quote! { - if cur.option_is_none() { - Ok(None) - } else { - Ok(Some(cur.into())) - } - } + // Here is a warning: this `if` has identical blocks + // } else if has_from { + // quote! { + // if cur.option_is_none() { + // Ok(None) + // } else { + // Ok(Some(cur.try_into()?)) + // } + // } } else { quote! { if cur.option_is_none() { @@ -556,12 +670,15 @@ impl TypeCategory { } TypeCategory::Type => quote! { Ok(cur.into()) }, TypeCategory::Primitive => quote! { cur.try_into() }, - TypeCategory::Array => quote! { Ok(cur) }, + TypeCategory::Array => quote! { cur.try_into() }, TypeCategory::FixVec => { quote! { cur.convert_to_rawbytes() } } + TypeCategory::Union => { + quote!(cur.try_into()) + } } } } @@ -591,7 +708,8 @@ fn get_rust_type_category(typ: &TopDecl) -> (TokenStream, TypeCategory) { if let TopDecl::Primitive(_) = a.item().typ().as_ref() { // array of byte tc = TypeCategory::Array; - quote! { Cursor } + let len = a.item_count(); + quote! { [u8; #len] } } else { // array of Types tc = TypeCategory::Type; @@ -628,6 +746,9 @@ fn get_rust_type_category(typ: &TopDecl) -> (TokenStream, TypeCategory) { } } } + TopDecl::Union(_) => { + tc = TypeCategory::Union; + } _ => { tc = TypeCategory::Type; } @@ -679,15 +800,23 @@ fn verify_typ(typ: &TopDecl, q_val: TokenStream) -> TokenStream { #q_val.verify(compatible)?; ) } - TopDecl::Array(_) => { + TopDecl::Array(sub_typ) => { let type_name_lower = typ.name().to_lowercase(); match type_name_lower.as_ref() { "uint8" | "int8" | "uint16" | "int16" | "uint32" | "int32" | "uint64" | "int64" => { quote!() } - _ => quote!( - #type_name::from(#q_val).verify(compatible)?; - ), + _ => { + if let TopDecl::Primitive(_) = sub_typ.item().typ().as_ref() { + quote!( + #type_name::from(Cursor::try_from(#q_val)?).verify(compatible)?; + ) + } else { + quote!( + #type_name::from(#q_val).verify(compatible)?; + ) + } + } } } TopDecl::Struct(_) => { diff --git a/tools/codegen/src/generator/languages/rust_lazy_reader/mod.rs b/tools/codegen/src/generator/languages/rust_lazy_reader/mod.rs index 23f6faf..9e387b9 100644 --- a/tools/codegen/src/generator/languages/rust_lazy_reader/mod.rs +++ b/tools/codegen/src/generator/languages/rust_lazy_reader/mod.rs @@ -14,8 +14,7 @@ impl super::LanguageGenerator for Generator { output, r#" extern crate alloc; - use molecule::lazy_reader::Cursor; - use molecule::lazy_reader::Error; + use molecule::lazy_reader::{{Cursor, Error, NUMBER_SIZE}}; use core::convert::TryInto;"# )?; @@ -44,6 +43,24 @@ fn ident_new(name: &str) -> Ident { Ident::new(name, proc_macro2::Span::call_site()) } +fn ident_new_camel(name: &str) -> Ident { + let mut camel_case = String::new(); + let mut capitalize_next = true; + + for c in name.chars() { + if c == '_' { + capitalize_next = true; + } else if capitalize_next { + camel_case.push(c.to_ascii_uppercase()); + capitalize_next = false; + } else { + camel_case.push(c); + } + } + + ident_new(&camel_case) +} + pub trait LazyReaderGenerator: HasName { fn gen_rust(&self, output: &mut W) -> io::Result<()> { let name = ident_new(self.name()); diff --git a/tools/compiler/Cargo.lock b/tools/compiler/Cargo.lock index 79d0a0e..993e01e 100644 --- a/tools/compiler/Cargo.lock +++ b/tools/compiler/Cargo.lock @@ -243,7 +243,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -274,7 +274,7 @@ checksum = "889bff6ebe76dbef2685598944997eb7f15c9854a2e34db853a51c6ac158b9d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.96", ] [[package]] @@ -336,7 +336,7 @@ checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -509,4 +509,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" dependencies = [ "linked-hash-map", -] +] \ No newline at end of file