From 703b9e942610d767711d3fd3b2792364d32aa88a Mon Sep 17 00:00:00 2001 From: xjd Date: Wed, 23 Aug 2023 15:08:05 +0800 Subject: [PATCH] Fixes to reviews * Support iterator * Change read_at as method * sub_size returns Result * Check alignment on get_item_count * Snake names * Some typos --- Makefile | 1 - bindings/rust/src/lazy_reader.rs | 134 ++++++++++-------- examples/lazy-reader-tests/build.rs | 16 ++- examples/lazy-reader-tests/src/lib.rs | 10 +- examples/lazy-reader-tests/src/types_api2.rs | 1 + examples/lazy-reader-tests/src/types_array.rs | 20 +-- .../src/types_moleculec_check.rs | 52 +++---- .../lazy-reader-tests/src/types_struct.rs | 2 +- examples/lazy-reader-tests/src/types_vec.rs | 24 ++-- .../languages/rust_lazy_reader/generator.rs | 73 +++++++++- 10 files changed, 213 insertions(+), 120 deletions(-) diff --git a/Makefile b/Makefile index d8c8650..bffb7e7 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,6 @@ clippy: @set -eu; \ for dir in ${RUST_PROJS}; do \ cd "$${dir}"; \ - cargo clean; \ cargo clippy --all --all-targets --all-features; \ cd - > /dev/null; \ done diff --git a/bindings/rust/src/lazy_reader.rs b/bindings/rust/src/lazy_reader.rs index 6554482..09f95ed 100644 --- a/bindings/rust/src/lazy_reader.rs +++ b/bindings/rust/src/lazy_reader.rs @@ -58,49 +58,6 @@ pub struct Union { pub cursor: Cursor, } -pub fn read_at(cur: &Cursor, buf: &mut [u8]) -> Result { - let read_len = min(cur.size, buf.len()); - let ds = &mut *cur.data_source.borrow_mut(); - if read_len > ds.cache.len() { - return ds.reader.read(buf, cur.offset); - } - if cur.offset < ds.cache_start_point - || (cur.offset + read_len) > (ds.cache_start_point + ds.cache_size) - { - let reader = &ds.reader; - let size = reader.read(&mut ds.cache[..], cur.offset).unwrap(); - if size < read_len { - return Err(Error::Read(format!( - "read_at `if size({}) < read_len({})`", - size, read_len - ))); - } - ds.cache_size = size; - ds.cache_start_point = cur.offset; - - if ds.cache_size > ds.cache.len() { - return Err(Error::Read(format!( - "read_at `if ds.cache_size({}) > ds.cache.len()({})`", - ds.cache_size, - ds.cache.len() - ))); - } - } - if cur.offset < ds.cache_start_point || (cur.offset - ds.cache_start_point) > ds.cache.len() { - return Err(Error::Read( - "read_at `if cur.offset < ds.start_point || ...`".into(), - )); - } - let read_point = cur.offset - ds.cache_start_point; - if read_point + read_len > ds.cache_size { - return Err(Error::Read( - "read_at `if read_point + read_len > ds.cache_size`".into(), - )); - } - buf.copy_from_slice(&ds.cache[read_point..(read_point + read_len)]); - Ok(read_len) -} - impl Cursor { /** cache_size: normally it can be set to MAX_CACHE_SIZE(2K) @@ -122,13 +79,63 @@ impl Cursor { data_source: Rc::new(RefCell::new(data_source)), } } + pub fn read_at(&self, buf: &mut [u8]) -> Result { + let read_len = min(self.size, buf.len()); + let ds = &mut *self.data_source.borrow_mut(); + if read_len > ds.cache.len() { + return ds.reader.read(buf, self.offset); + } + if self.offset < ds.cache_start_point + || (self.offset + read_len) > (ds.cache_start_point + ds.cache_size) + { + let reader = &ds.reader; + let size = reader.read(&mut ds.cache[..], self.offset).unwrap(); + if size < read_len { + return Err(Error::Read(format!( + "read_at `if size({}) < read_len({})`", + size, read_len + ))); + } + ds.cache_size = size; + ds.cache_start_point = self.offset; + + if ds.cache_size > ds.cache.len() { + return Err(Error::Read(format!( + "read_at `if ds.cache_size({}) > ds.cache.len()({})`", + ds.cache_size, + ds.cache.len() + ))); + } + } + if self.offset < ds.cache_start_point + || (self.offset - ds.cache_start_point) > ds.cache.len() + { + return Err(Error::Read( + "read_at `if cur.offset < ds.start_point || ...`".into(), + )); + } + let read_point = self.offset - ds.cache_start_point; + if read_point + read_len > ds.cache_size { + return Err(Error::Read( + "read_at `if read_point + read_len > ds.cache_size`".into(), + )); + } + buf.copy_from_slice(&ds.cache[read_point..(read_point + read_len)]); + Ok(read_len) + } pub fn add_offset(&mut self, offset: usize) { self.offset = self.offset.checked_add(offset).unwrap(); } - pub fn sub_size(&mut self, shrink_size: usize) { - self.size = self.size.checked_sub(shrink_size).unwrap(); + pub fn sub_size(&mut self, shrink_size: usize) -> Result<(), Error> { + self.size = self.size.checked_sub(shrink_size).ok_or_else(|| { + Error::Overflow(format!( + "sub_size: self.size({}) - shrink_size({}) failed", + self.size, shrink_size + )) + })?; + Ok(()) } pub fn validate(&self) -> Result<(), Error> { @@ -147,7 +154,7 @@ impl Cursor { pub fn unpack_number(&self) -> Result { let mut src = [0u8; 4]; - let size = read_at(self, &mut src[..]).unwrap(); + let size = self.read_at(&mut src[..])?; if size != 4 { Err(Error::FieldCount("unpack_number".into())) } else { @@ -210,14 +217,21 @@ impl Cursor { } else { let mut cur2 = self.clone(); cur2.add_offset(NUM_T_SIZE); - cur2.sub_size(NUM_T_SIZE); + cur2.sub_size(NUM_T_SIZE)?; cur2.validate()?; cur2.get_item_count() } } pub fn get_item_count(&self) -> Result { - let count = self.unpack_number()? / 4; + let len = self.unpack_number()?; + if len % 4 != 0 { + return Err(Error::UnknownItem(format!( + "get_item_count not aligned, len = {}", + len + ))); + } + let count = len / 4; if count == 0 { Err(Error::UnknownItem("get_item_count".into())) } else { @@ -283,7 +297,7 @@ impl Cursor { res.offset = self.offset; res.add_offset(item_start); res.size = total_size; - res.sub_size(item_start) + res.sub_size(item_start)?; } else { temp.offset = self.offset; let calc_offset = calculate_offset(NUM_T_SIZE, item_index + 2, 0); @@ -293,7 +307,7 @@ impl Cursor { res.offset = self.offset; res.add_offset(item_start); res.size = item_end; - res.sub_size(item_start); + res.sub_size(item_start)?; } res.validate()?; Ok(res) @@ -323,7 +337,7 @@ impl Cursor { let item_id = self.unpack_number()?; let mut cursor = self.clone(); cursor.add_offset(NUM_T_SIZE); - cursor.sub_size(NUM_T_SIZE); + cursor.sub_size(NUM_T_SIZE)?; cursor.validate()?; Ok(Union { item_id, cursor }) } @@ -338,7 +352,7 @@ impl TryFrom for u64 { type Error = Error; fn try_from(cur: Cursor) -> Result { let mut buf = [0u8; 8]; - let size = read_at(&cur, &mut buf[..])?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { Err(Error::FieldCount("convert_to_u64".into())) } else { @@ -351,7 +365,7 @@ impl TryFrom for i64 { type Error = Error; fn try_from(cur: Cursor) -> Result { let mut buf = [0u8; 8]; - let size = read_at(&cur, &mut buf[..])?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { Err(Error::FieldCount("convert_to_i64".into())) } else { @@ -364,7 +378,7 @@ impl TryFrom for u32 { type Error = Error; fn try_from(cur: Cursor) -> Result { let mut buf = [0u8; 4]; - let size = read_at(&cur, &mut buf[..])?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { Err(Error::FieldCount("convert_to_u32".into())) } else { @@ -377,7 +391,7 @@ impl TryFrom for i32 { type Error = Error; fn try_from(cur: Cursor) -> Result { let mut buf = [0u8; 4]; - let size = read_at(&cur, &mut buf[..])?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { Err(Error::FieldCount("convert_to_i32".into())) } else { @@ -390,7 +404,7 @@ impl TryFrom for u16 { type Error = Error; fn try_from(cur: Cursor) -> Result { let mut buf = [0u8; 2]; - let size = read_at(&cur, &mut buf[..])?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { Err(Error::FieldCount("convert_to_u16".into())) } else { @@ -403,7 +417,7 @@ impl TryFrom for i16 { type Error = Error; fn try_from(cur: Cursor) -> Result { let mut buf = [0u8; 2]; - let size = read_at(&cur, &mut buf[..])?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { Err(Error::FieldCount("convert_to_i16".into())) } else { @@ -416,7 +430,7 @@ impl TryFrom for u8 { type Error = Error; fn try_from(cur: Cursor) -> Result { let mut buf = [0u8; 1]; - let size = read_at(&cur, &mut buf[..])?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { Err(Error::FieldCount("convert_to_u8".into())) } else { @@ -429,7 +443,7 @@ impl TryFrom for i8 { type Error = Error; fn try_from(cur: Cursor) -> Result { let mut buf = [0u8; 1]; - let size = read_at(&cur, &mut buf[..])?; + let size = cur.read_at(&mut buf[..])?; if size != buf.len() { Err(Error::FieldCount("convert_to_i8".into())) } else { @@ -444,7 +458,7 @@ impl TryFrom for Vec { let mut buf = Vec::::new(); buf.resize(cur.size, 0); - let size = read_at(&cur, buf.as_mut_slice())?; + let size = cur.read_at(buf.as_mut_slice())?; if size != buf.len() { return Err(Error::Read(format!( "size({}) != buf.len()({})", diff --git a/examples/lazy-reader-tests/build.rs b/examples/lazy-reader-tests/build.rs index d964f63..7a58446 100644 --- a/examples/lazy-reader-tests/build.rs +++ b/examples/lazy-reader-tests/build.rs @@ -1,5 +1,10 @@ use codegen::{Compiler, Language}; -use std::{env, fs, path}; +use std::ffi::OsStr; +use std::process::Command; +use std::{ + env, fs, + path::{self, PathBuf}, +}; fn compile_schema_rust(schema: &str) { let mut compiler = Compiler::new(); @@ -10,6 +15,7 @@ fn compile_schema_rust(schema: &str) { .output_dir(out_dir) .run() .unwrap(); + println!("cargo:rerun-if-changed={}", schema); } @@ -18,12 +24,20 @@ fn compile_schema_rust_lazy_reader(schema: &str) { let mut out_dir = path::PathBuf::from(&env::var("OUT_DIR").unwrap_or_else(|_| ".".to_string())); out_dir.push("lazy_reader"); drop(fs::create_dir(&out_dir)); + let mut file_path = out_dir.clone(); compiler .input_schema_file(schema) .generate_code(Language::RustLazyReader) .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 053cf50..982de87 100644 --- a/examples/lazy-reader-tests/src/lib.rs +++ b/examples/lazy-reader-tests/src/lib.rs @@ -78,7 +78,7 @@ impl TypesCheckErr { Self::Mol2Err(v) => v, } } - pub fn check_lenght(l1: usize, l2: usize) -> Result<(), Self> { + pub fn check_length(l1: usize, l2: usize) -> Result<(), Self> { if l1 == l2 { Ok(()) } else { @@ -98,7 +98,7 @@ impl TypesCheckErr { } pub fn check_data>(d1: &T, d2: &[T1]) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_1_data(&d1.mol_get(i)?, &d2[i])?; @@ -111,7 +111,7 @@ impl TypesCheckErr { d1: &T1, d2: &T2, ) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.mol_len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.mol_len()?)?; for i in 0..d1.mol_len()? { TypesCheckErr::check_1_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } @@ -204,12 +204,12 @@ impl TypesUnionA { 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_structa()?), + 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_table6opt()?), + Self::Table6Opt(v) => v.check(&d.as_table6_opt()?), } } } diff --git a/examples/lazy-reader-tests/src/types_api2.rs b/examples/lazy-reader-tests/src/types_api2.rs index 1299680..4b046c1 100644 --- a/examples/lazy-reader-tests/src/types_api2.rs +++ b/examples/lazy-reader-tests/src/types_api2.rs @@ -1,4 +1,5 @@ #![allow(unused_imports)] +#![allow(dead_code)] include!(concat!( env!("OUT_DIR"), diff --git a/examples/lazy-reader-tests/src/types_array.rs b/examples/lazy-reader-tests/src/types_array.rs index 000ec39..75b64bf 100644 --- a/examples/lazy-reader-tests/src/types_array.rs +++ b/examples/lazy-reader-tests/src/types_array.rs @@ -231,7 +231,7 @@ impl TypesArray { .build() } pub fn check(&self, d: &types_api2::Word3) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -245,7 +245,7 @@ impl TypesArray { .build() } pub fn check(&self, d: &types_api2::Word4) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -259,7 +259,7 @@ impl TypesArray { .build() } pub fn check(&self, d: &types_api2::Word5) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -273,7 +273,7 @@ impl TypesArray { .build() } pub fn check(&self, d: &types_api2::Word6) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -287,7 +287,7 @@ impl TypesArray { .build() } pub fn check(&self, d: &types_api2::Word7) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -301,7 +301,7 @@ impl TypesArray { .build() } pub fn check(&self, d: &types_api2::Word8) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -315,7 +315,7 @@ impl TypesArray, 3> { .build() } pub fn check(&self, d: &types_api2::Byte3x3) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -330,7 +330,7 @@ impl TypesArray, 3> { } pub fn check(&self, d: &types_api2::Byte5x3) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -344,7 +344,7 @@ impl TypesArray, 3> { .build() } pub fn check(&self, d: &types_api2::Byte7x3) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } @@ -358,7 +358,7 @@ impl TypesArray, 3> { .build() } pub fn check(&self, d: &types_api2::Byte9x3) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { self.d[i].check(&d.get(i)?.into())?; } diff --git a/examples/lazy-reader-tests/src/types_moleculec_check.rs b/examples/lazy-reader-tests/src/types_moleculec_check.rs index 4ef38a5..4e052f9 100644 --- a/examples/lazy-reader-tests/src/types_moleculec_check.rs +++ b/examples/lazy-reader-tests/src/types_moleculec_check.rs @@ -152,77 +152,77 @@ pub fn check_f16(d1: &types_api::Word, d2: &types_api2::Word) -> ResCheckErr { TypesCheckErr::check_mol_data(d1, d2) } pub fn check_f17(d1: &types_api::Word2, d2: &types_api2::Word2) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f18(d1: &types_api::Word3, d2: &types_api2::Word3) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f19(d1: &types_api::Word4, d2: &types_api2::Word4) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f20(d1: &types_api::Word5, d2: &types_api2::Word5) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f21(d1: &types_api::Word6, d2: &types_api2::Word6) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f22(d1: &types_api::Word7, d2: &types_api2::Word7) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f23(d1: &types_api::Word8, d2: &types_api2::Word8) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f24(d1: &types_api::Byte3x3, d2: &types_api2::Byte3x3) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f25(d1: &types_api::Byte5x3, d2: &types_api2::Byte5x3) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f26(d1: &types_api::Byte7x3, d2: &types_api2::Byte7x3) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f27(d1: &types_api::Byte9x3, d2: &types_api2::Byte9x3) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } @@ -304,7 +304,7 @@ pub fn check_f37(d1: &types_api::StructJ, d2: &types_api2::StructJ) -> ResCheckE Ok(()) } pub fn check_f38(d1: &types_api::StructIx3, d2: &types_api2::StructIx3) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len())?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len())?; for i in 0..d1.mol_len()? { check_f36(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } @@ -329,56 +329,56 @@ pub fn check_f41(d1: &types_api::Bytes, d2: &Cursor) -> ResCheckErr { TypesCheckErr::check_mol_data(d1, &d2) } pub fn check_f42(d1: &types_api::Words, d2: &types_api2::Words) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f43(d1: &types_api::Byte3Vec, d2: &types_api2::Byte3Vec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f44(d1: &types_api::Byte7Vec, d2: &types_api2::Byte7Vec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { TypesCheckErr::check_mol_data(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f45(d1: &types_api::StructIVec, d2: &types_api2::StructIVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { check_f36(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f46(d1: &types_api::StructJVec, d2: &types_api2::StructJVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { check_f37(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f47(d1: &types_api::StructPVec, d2: &types_api2::StructPVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { check_f40(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f48(d1: &types_api::BytesVec, d2: &types_api2::BytesVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { check_f41(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } Ok(()) } pub fn check_f49(d1: &types_api::WordsVec, d2: &types_api2::WordsVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + TypesCheckErr::check_length(d1.mol_len()?, d2.len()?)?; for i in 0..d1.mol_len()? { check_f42(&d1.mol_get(i)?, &d2.mol_get(i)?)?; } @@ -619,7 +619,7 @@ pub fn check_f67( Ok(()) } pub fn check_f68(d1: &types_api::ByteOptVec, d2: &types_api2::ByteOptVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + 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)?; @@ -628,7 +628,7 @@ pub fn check_f68(d1: &types_api::ByteOptVec, d2: &types_api2::ByteOptVec) -> Res Ok(()) } pub fn check_f69(d1: &types_api::WordOptVec, d2: &types_api2::WordOptVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + 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()); @@ -637,7 +637,7 @@ pub fn check_f69(d1: &types_api::WordOptVec, d2: &types_api2::WordOptVec) -> Res Ok(()) } pub fn check_f70(d1: &types_api::WordsOptVec, d2: &types_api2::WordsOptVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + 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()); @@ -646,7 +646,7 @@ pub fn check_f70(d1: &types_api::WordsOptVec, d2: &types_api2::WordsOptVec) -> R Ok(()) } pub fn check_f71(d1: &types_api::BytesOptVec, d2: &types_api2::BytesOptVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d1.mol_len()?, d2.len()?)?; + 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.try_into().unwrap()); @@ -665,7 +665,7 @@ pub fn check_f72(d1: &types_api::UnionA, d2: &types_api2::UnionA) -> ResCheckErr check_f16(&v, &v2.into())?; } types_api::UnionAUnion::StructA(v) => { - let v2 = d2.as_structa()?; + let v2 = d2.as_struct_a()?; check_f28(&v, &v2)?; } types_api::UnionAUnion::Bytes(v) => { @@ -685,7 +685,7 @@ pub fn check_f72(d1: &types_api::UnionA, d2: &types_api2::UnionA) -> ResCheckErr check_f56(&v, &v2)?; } types_api::UnionAUnion::Table6Opt(v) => { - let v2 = d2.as_table6opt()?; + let v2 = d2.as_table6_opt()?; check_f66(&v.to_opt(), &v2)?; } }; diff --git a/examples/lazy-reader-tests/src/types_struct.rs b/examples/lazy-reader-tests/src/types_struct.rs index 5c02eef..918c38a 100644 --- a/examples/lazy-reader-tests/src/types_struct.rs +++ b/examples/lazy-reader-tests/src/types_struct.rs @@ -240,7 +240,7 @@ impl TypesStructIx3 { .build() } pub fn check(&self, d: &types_api2::StructIx3) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len(), self.d.len())?; + TypesCheckErr::check_length(d.len(), self.d.len())?; for i in 0..d.len() { let dd = d.get(i)?; self.d[i].check(&dd)?; diff --git a/examples/lazy-reader-tests/src/types_vec.rs b/examples/lazy-reader-tests/src/types_vec.rs index ea87eb5..7789c22 100644 --- a/examples/lazy-reader-tests/src/types_vec.rs +++ b/examples/lazy-reader-tests/src/types_vec.rs @@ -48,7 +48,7 @@ impl TypesVec { .build() } pub fn check(&self, d: &types_api2::Words) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.into())?; } @@ -62,7 +62,7 @@ impl TypesVec> { .build() } pub fn check(&self, d: &types_api2::Byte3Vec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.into())?; } @@ -76,7 +76,7 @@ impl TypesVec> { .build() } pub fn check(&self, d: &types_api2::Byte7Vec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.into())?; } @@ -90,7 +90,7 @@ impl TypesVec { .build() } pub fn check(&self, d: &types_api2::StructIVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?)?; } @@ -104,7 +104,7 @@ impl TypesVec { .build() } pub fn check(&self, d: &types_api2::StructJVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?)?; } @@ -118,7 +118,7 @@ impl TypesVec { .build() } pub fn check(&self, d: &types_api2::StructPVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?)?; } @@ -132,7 +132,7 @@ impl TypesVec> { .build() } pub fn check(&self, d: &types_api2::BytesVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.try_into().unwrap())?; } @@ -155,7 +155,7 @@ impl TypesVec> { .build() } pub fn check(&self, d: &types_api2::WordsVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.into())?; } @@ -169,7 +169,7 @@ impl TypesVec> { .build() } pub fn check(&self, d: &types_api2::ByteOptVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.into())?; } @@ -183,7 +183,7 @@ impl TypesVec> { .build() } pub fn check(&self, d: &types_api2::WordOptVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.into())?; } @@ -197,7 +197,7 @@ impl TypesVec>> { .build() } pub fn check(&self, d: &types_api2::WordsOptVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.into())?; } @@ -211,7 +211,7 @@ impl TypesVec>> { .build() } pub fn check(&self, d: &types_api2::BytesOptVec) -> ResCheckErr { - TypesCheckErr::check_lenght(d.len()?, self.d.len())?; + TypesCheckErr::check_length(d.len()?, self.d.len())?; for i in 0..d.len()? { self.d[i].check(&d.get(i)?.into())?; } 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 a809220..995ace3 100644 --- a/tools/codegen/src/generator/languages/rust_lazy_reader/generator.rs +++ b/tools/codegen/src/generator/languages/rust_lazy_reader/generator.rs @@ -19,6 +19,7 @@ use super::{ident_new, LazyReaderGenerator}; /// - common array, the set of Array, FixVec and DynVec, they share method like "len", "get" /// - common table, the set of Table, Struct, they share same method like ".t->XXX" use crate::ast::{self, HasName, *}; +use case::CaseExt; use proc_macro2::{Literal, TokenStream}; use quote::quote; use std::io; @@ -49,7 +50,7 @@ impl LazyReaderGenerator for ast::Union { for item in self.items() { let item_type_name = item.typ().name(); - let item_type_name = ident_new(&format!("as_{}", item_type_name.to_lowercase())); + 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! { @@ -175,7 +176,6 @@ fn generate_rust_common_array( }; writeln!(output, "{}", q)?; } - generate_rust_common_array_impl(output, name, type_name, tc, array, fixvec)?; Ok(()) } @@ -183,7 +183,7 @@ fn generate_rust_common_array( fn generate_rust_common_array_impl( output: &mut W, name: &str, - type_name: TokenStream, + item_name: TokenStream, tc: TypeCategory, array: Option<&Array>, fixvec: Option<&FixVec>, @@ -199,15 +199,80 @@ fn generate_rust_common_array_impl( }; let convert_code = tc.gen_convert_code(); let name = ident_new(name); + let iterator_name = ident_new(&format!("{}Iterator", name)); + let iterator_ref_name = ident_new(&format!("{}IteratorRef", name)); let q = quote! { impl #name { - pub fn get(&self, index: usize) -> Result<#type_name, Error> { + pub fn get(&self, index: usize) -> Result<#item_name, Error> { let cur = self.cursor.#slice_by?; #convert_code } } }; writeln!(output, "{}", q)?; + + if array.is_some() { + return Ok(()); + } + let q = quote! { + pub struct #iterator_name { + cur: #name, + index: usize, + len: usize, + } + impl core::iter::Iterator for #iterator_name { + type Item = #item_name; + fn next(&mut self) -> Option { + if self.index >= self.len { + None + } else { + let res = self.cur.get(self.index).unwrap(); + self.index += 1; + Some(res) + } + } + } + impl core::iter::IntoIterator for #name { + type Item = #item_name; + type IntoIter = #iterator_name; + fn into_iter(self) -> Self::IntoIter { + let len = self.len().unwrap(); + Self::IntoIter { + cur: self, + index: 0, + len + } + } + } + pub struct #iterator_ref_name<'a> { + cur: &'a #name, + index: usize, + len: usize + } + impl<'a> core::iter::Iterator for #iterator_ref_name<'a> { + type Item = #item_name; + fn next(&mut self) -> Option { + if self.index >= self.len { + None + } else { + let res = self.cur.get(self.index).unwrap(); + self.index += 1; + Some(res) + } + } + } + impl #name { + fn iter(&self) -> #iterator_ref_name { + let len = self.len().unwrap(); + #iterator_ref_name { + cur: &self, + index: 0, + len + } + } + } + }; + writeln!(output, "{}", q)?; Ok(()) }