diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1ff0526..36eb67d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -6,14 +6,14 @@ jobs: Build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Install Rust components run: rustup component add rustfmt && rustup component add clippy - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly-2021-08-16 + toolchain: nightly-2021-12-25 override: true - uses: docker-practice/actions-setup-docker@master diff --git a/Cargo.lock b/Cargo.lock index 3f5eae0..d43a641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,7 +228,7 @@ name = "cota-smt" version = "0.1.0" dependencies = [ "blake2b-ref 0.3.0", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "ckb-std", "ckb-types", "molecule", diff --git a/Cargo.toml b/Cargo.toml index ba70c75..7c06c8e 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,12 +4,12 @@ version = "0.1.0" edition = "2018" [dependencies] -cfg-if = "0.1" +cfg-if = "1.0" blake2b-ref = "0.3" ckb-std = {version = "0.9.0", optional = true} ckb-types = {version = "0.101.1", optional = true} molecule = {version = "0.7.2", default_features = false, optional = true} -sparse-merkle-tree = {version = "0.5.2", default_features = false} +sparse-merkle-tree = {version = "0.5.3", default_features = false} [features] diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..f45d8f1 --- /dev/null +++ b/renovate.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "config:base" + ] +} diff --git a/rust-toolchain b/rust-toolchain index b5ccd17..15a53c9 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2021-08-16 \ No newline at end of file +nightly-2021-12-25 \ No newline at end of file diff --git a/src/common.mol b/src/common.mol index de25704..ad20dfe 100644 --- a/src/common.mol +++ b/src/common.mol @@ -54,4 +54,22 @@ struct ClaimCotaNFTKey { } vector ClaimCotaNFTKeyVec ; vector ClaimCotaNFTValueVec ; -vector ClaimCotaNFTInfoVec ; \ No newline at end of file +struct ClaimCotaNFTInfo { + version: byte, + nft_info: CotaNFTInfo, +} +vector ClaimCotaNFTInfoVec ; + + +// V1 +struct WithdrawalCotaNFTKeyV1 { + nft_id: CotaNFTId, + out_point: OutPointSlice, +} +vector WithdrawalCotaNFTKeyV1Vec ; + +table WithdrawalCotaNFTValueV1 { + nft_info: CotaNFTInfo, + to_lock: Bytes, +} +vector WithdrawalCotaNFTValueV1Vec ; diff --git a/src/common.rs b/src/common.rs index dcca3e3..1057457 100644 --- a/src/common.rs +++ b/src/common.rs @@ -9,7 +9,6 @@ use super::molecule::{self, prelude::*}; extern crate alloc; pub use alloc::vec::*; // these lines above are manually added -// replace "::molecule" to "molecule" in below code use molecule::prelude::*; #[derive(Clone)] @@ -6871,6 +6870,195 @@ impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator for ClaimCotaNFTValueVecReaderI } } #[derive(Clone)] +pub struct ClaimCotaNFTInfo(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ClaimCotaNFTInfo { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ClaimCotaNFTInfo { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ClaimCotaNFTInfo { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "version", self.version())?; + write!(f, ", {}: {}", "nft_info", self.nft_info())?; + write!(f, " }}") + } +} +impl ::core::default::Default for ClaimCotaNFTInfo { + fn default() -> Self { + let v: Vec = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + ClaimCotaNFTInfo::new_unchecked(v.into()) + } +} +impl ClaimCotaNFTInfo { + pub const FIELD_COUNT: usize = 2; + pub const FIELD_SIZES: [usize; 2] = [1, 22]; + pub const TOTAL_SIZE: usize = 23; + + pub fn version(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + + pub fn nft_info(&self) -> CotaNFTInfo { + CotaNFTInfo::new_unchecked(self.0.slice(1..23)) + } + + pub fn as_reader<'r>(&'r self) -> ClaimCotaNFTInfoReader<'r> { + ClaimCotaNFTInfoReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ClaimCotaNFTInfo { + type Builder = ClaimCotaNFTInfoBuilder; + + const NAME: &'static str = "ClaimCotaNFTInfo"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ClaimCotaNFTInfo(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ClaimCotaNFTInfoReader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ClaimCotaNFTInfoReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .version(self.version()) + .nft_info(self.nft_info()) + } +} +#[derive(Clone, Copy)] +pub struct ClaimCotaNFTInfoReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ClaimCotaNFTInfoReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ClaimCotaNFTInfoReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ClaimCotaNFTInfoReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "version", self.version())?; + write!(f, ", {}: {}", "nft_info", self.nft_info())?; + write!(f, " }}") + } +} +impl<'r> ClaimCotaNFTInfoReader<'r> { + pub const FIELD_COUNT: usize = 2; + pub const FIELD_SIZES: [usize; 2] = [1, 22]; + pub const TOTAL_SIZE: usize = 23; + + pub fn version(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + + pub fn nft_info(&self) -> CotaNFTInfoReader<'r> { + CotaNFTInfoReader::new_unchecked(&self.as_slice()[1..23]) + } +} +impl<'r> molecule::prelude::Reader<'r> for ClaimCotaNFTInfoReader<'r> { + type Entity = ClaimCotaNFTInfo; + + const NAME: &'static str = "ClaimCotaNFTInfoReader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + ClaimCotaNFTInfoReader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct ClaimCotaNFTInfoBuilder { + pub(crate) version: Byte, + pub(crate) nft_info: CotaNFTInfo, +} +impl ClaimCotaNFTInfoBuilder { + pub const FIELD_COUNT: usize = 2; + pub const FIELD_SIZES: [usize; 2] = [1, 22]; + pub const TOTAL_SIZE: usize = 23; + + pub fn version(mut self, v: Byte) -> Self { + self.version = v; + self + } + + pub fn nft_info(mut self, v: CotaNFTInfo) -> Self { + self.nft_info = v; + self + } +} +impl molecule::prelude::Builder for ClaimCotaNFTInfoBuilder { + type Entity = ClaimCotaNFTInfo; + + const NAME: &'static str = "ClaimCotaNFTInfoBuilder"; + + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.version.as_slice())?; + writer.write_all(self.nft_info.as_slice())?; + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ClaimCotaNFTInfo::new_unchecked(inner.into()) + } +} +#[derive(Clone)] pub struct ClaimCotaNFTInfoVec(molecule::bytes::Bytes); impl ::core::fmt::LowerHex for ClaimCotaNFTInfoVec { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { @@ -6906,7 +7094,7 @@ impl ::core::default::Default for ClaimCotaNFTInfoVec { } } impl ClaimCotaNFTInfoVec { - pub const ITEM_SIZE: usize = 22; + pub const ITEM_SIZE: usize = 23; pub fn total_size(&self) -> usize { molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.item_count() @@ -6924,7 +7112,7 @@ impl ClaimCotaNFTInfoVec { self.len() == 0 } - pub fn get(&self, idx: usize) -> Option { + pub fn get(&self, idx: usize) -> Option { if idx >= self.len() { None } else { @@ -6932,10 +7120,10 @@ impl ClaimCotaNFTInfoVec { } } - pub fn get_unchecked(&self, idx: usize) -> CotaNFTInfo { + pub fn get_unchecked(&self, idx: usize) -> ClaimCotaNFTInfo { let start = molecule::NUMBER_SIZE + Self::ITEM_SIZE * idx; let end = start + Self::ITEM_SIZE; - CotaNFTInfo::new_unchecked(self.0.slice(start..end)) + ClaimCotaNFTInfo::new_unchecked(self.0.slice(start..end)) } pub fn as_reader<'r>(&'r self) -> ClaimCotaNFTInfoVecReader<'r> { @@ -7005,7 +7193,7 @@ impl<'r> ::core::fmt::Display for ClaimCotaNFTInfoVecReader<'r> { } } impl<'r> ClaimCotaNFTInfoVecReader<'r> { - pub const ITEM_SIZE: usize = 22; + pub const ITEM_SIZE: usize = 23; pub fn total_size(&self) -> usize { molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.item_count() @@ -7023,7 +7211,7 @@ impl<'r> ClaimCotaNFTInfoVecReader<'r> { self.len() == 0 } - pub fn get(&self, idx: usize) -> Option> { + pub fn get(&self, idx: usize) -> Option> { if idx >= self.len() { None } else { @@ -7031,10 +7219,10 @@ impl<'r> ClaimCotaNFTInfoVecReader<'r> { } } - pub fn get_unchecked(&self, idx: usize) -> CotaNFTInfoReader<'r> { + pub fn get_unchecked(&self, idx: usize) -> ClaimCotaNFTInfoReader<'r> { let start = molecule::NUMBER_SIZE + Self::ITEM_SIZE * idx; let end = start + Self::ITEM_SIZE; - CotaNFTInfoReader::new_unchecked(&self.as_slice()[start..end]) + ClaimCotaNFTInfoReader::new_unchecked(&self.as_slice()[start..end]) } } impl<'r> molecule::prelude::Reader<'r> for ClaimCotaNFTInfoVecReader<'r> { @@ -7075,28 +7263,31 @@ impl<'r> molecule::prelude::Reader<'r> for ClaimCotaNFTInfoVecReader<'r> { } } #[derive(Debug, Default)] -pub struct ClaimCotaNFTInfoVecBuilder(pub(crate) Vec); +pub struct ClaimCotaNFTInfoVecBuilder(pub(crate) Vec); impl ClaimCotaNFTInfoVecBuilder { - pub const ITEM_SIZE: usize = 22; + pub const ITEM_SIZE: usize = 23; - pub fn set(mut self, v: Vec) -> Self { + pub fn set(mut self, v: Vec) -> Self { self.0 = v; self } - pub fn push(mut self, v: CotaNFTInfo) -> Self { + pub fn push(mut self, v: ClaimCotaNFTInfo) -> Self { self.0.push(v); self } - pub fn extend>(mut self, iter: T) -> Self { + pub fn extend>( + mut self, + iter: T, + ) -> Self { for elem in iter { self.0.push(elem); } self } - pub fn replace(&mut self, index: usize, v: CotaNFTInfo) -> Option { + pub fn replace(&mut self, index: usize, v: ClaimCotaNFTInfo) -> Option { self.0 .get_mut(index) .map(|item| ::core::mem::replace(item, v)) @@ -7128,7 +7319,7 @@ impl molecule::prelude::Builder for ClaimCotaNFTInfoVecBuilder { } pub struct ClaimCotaNFTInfoVecIterator(ClaimCotaNFTInfoVec, usize, usize); impl ::core::iter::Iterator for ClaimCotaNFTInfoVecIterator { - type Item = CotaNFTInfo; + type Item = ClaimCotaNFTInfo; fn next(&mut self) -> Option { if self.1 >= self.2 { @@ -7147,7 +7338,7 @@ impl ::core::iter::ExactSizeIterator for ClaimCotaNFTInfoVecIterator { } impl ::core::iter::IntoIterator for ClaimCotaNFTInfoVec { type IntoIter = ClaimCotaNFTInfoVecIterator; - type Item = CotaNFTInfo; + type Item = ClaimCotaNFTInfo; fn into_iter(self) -> Self::IntoIter { let len = self.len(); @@ -7165,7 +7356,7 @@ pub struct ClaimCotaNFTInfoVecReaderIterator<'t, 'r>( usize, ); impl<'t: 'r, 'r> ::core::iter::Iterator for ClaimCotaNFTInfoVecReaderIterator<'t, 'r> { - type Item = CotaNFTInfoReader<'t>; + type Item = ClaimCotaNFTInfoReader<'t>; fn next(&mut self) -> Option { if self.1 >= self.2 { @@ -7182,3 +7373,1200 @@ impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator for ClaimCotaNFTInfoVecReaderIt self.2 - self.1 } } +#[derive(Clone)] +pub struct WithdrawalCotaNFTKeyV1(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for WithdrawalCotaNFTKeyV1 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for WithdrawalCotaNFTKeyV1 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for WithdrawalCotaNFTKeyV1 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "nft_id", self.nft_id())?; + write!(f, ", {}: {}", "out_point", self.out_point())?; + write!(f, " }}") + } +} +impl ::core::default::Default for WithdrawalCotaNFTKeyV1 { + fn default() -> Self { + let v: Vec = vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + WithdrawalCotaNFTKeyV1::new_unchecked(v.into()) + } +} +impl WithdrawalCotaNFTKeyV1 { + pub const FIELD_COUNT: usize = 2; + pub const FIELD_SIZES: [usize; 2] = [26, 24]; + pub const TOTAL_SIZE: usize = 50; + + pub fn nft_id(&self) -> CotaNFTId { + CotaNFTId::new_unchecked(self.0.slice(0..26)) + } + + pub fn out_point(&self) -> OutPointSlice { + OutPointSlice::new_unchecked(self.0.slice(26..50)) + } + + pub fn as_reader<'r>(&'r self) -> WithdrawalCotaNFTKeyV1Reader<'r> { + WithdrawalCotaNFTKeyV1Reader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for WithdrawalCotaNFTKeyV1 { + type Builder = WithdrawalCotaNFTKeyV1Builder; + + const NAME: &'static str = "WithdrawalCotaNFTKeyV1"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + WithdrawalCotaNFTKeyV1(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTKeyV1Reader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTKeyV1Reader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .nft_id(self.nft_id()) + .out_point(self.out_point()) + } +} +#[derive(Clone, Copy)] +pub struct WithdrawalCotaNFTKeyV1Reader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for WithdrawalCotaNFTKeyV1Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for WithdrawalCotaNFTKeyV1Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for WithdrawalCotaNFTKeyV1Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "nft_id", self.nft_id())?; + write!(f, ", {}: {}", "out_point", self.out_point())?; + write!(f, " }}") + } +} +impl<'r> WithdrawalCotaNFTKeyV1Reader<'r> { + pub const FIELD_COUNT: usize = 2; + pub const FIELD_SIZES: [usize; 2] = [26, 24]; + pub const TOTAL_SIZE: usize = 50; + + pub fn nft_id(&self) -> CotaNFTIdReader<'r> { + CotaNFTIdReader::new_unchecked(&self.as_slice()[0..26]) + } + + pub fn out_point(&self) -> OutPointSliceReader<'r> { + OutPointSliceReader::new_unchecked(&self.as_slice()[26..50]) + } +} +impl<'r> molecule::prelude::Reader<'r> for WithdrawalCotaNFTKeyV1Reader<'r> { + type Entity = WithdrawalCotaNFTKeyV1; + + const NAME: &'static str = "WithdrawalCotaNFTKeyV1Reader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + WithdrawalCotaNFTKeyV1Reader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct WithdrawalCotaNFTKeyV1Builder { + pub(crate) nft_id: CotaNFTId, + pub(crate) out_point: OutPointSlice, +} +impl WithdrawalCotaNFTKeyV1Builder { + pub const FIELD_COUNT: usize = 2; + pub const FIELD_SIZES: [usize; 2] = [26, 24]; + pub const TOTAL_SIZE: usize = 50; + + pub fn nft_id(mut self, v: CotaNFTId) -> Self { + self.nft_id = v; + self + } + + pub fn out_point(mut self, v: OutPointSlice) -> Self { + self.out_point = v; + self + } +} +impl molecule::prelude::Builder for WithdrawalCotaNFTKeyV1Builder { + type Entity = WithdrawalCotaNFTKeyV1; + + const NAME: &'static str = "WithdrawalCotaNFTKeyV1Builder"; + + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.nft_id.as_slice())?; + writer.write_all(self.out_point.as_slice())?; + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + WithdrawalCotaNFTKeyV1::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct WithdrawalCotaNFTKeyV1Vec(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for WithdrawalCotaNFTKeyV1Vec { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for WithdrawalCotaNFTKeyV1Vec { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for WithdrawalCotaNFTKeyV1Vec { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + for i in 0..self.len() { + if i == 0 { + write!(f, "{}", self.get_unchecked(i))?; + } else { + write!(f, ", {}", self.get_unchecked(i))?; + } + } + write!(f, "]") + } +} +impl ::core::default::Default for WithdrawalCotaNFTKeyV1Vec { + fn default() -> Self { + let v: Vec = vec![0, 0, 0, 0]; + WithdrawalCotaNFTKeyV1Vec::new_unchecked(v.into()) + } +} +impl WithdrawalCotaNFTKeyV1Vec { + pub const ITEM_SIZE: usize = 50; + + pub fn total_size(&self) -> usize { + molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.item_count() + } + + pub fn item_count(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn len(&self) -> usize { + self.item_count() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn get(&self, idx: usize) -> Option { + if idx >= self.len() { + None + } else { + Some(self.get_unchecked(idx)) + } + } + + pub fn get_unchecked(&self, idx: usize) -> WithdrawalCotaNFTKeyV1 { + let start = molecule::NUMBER_SIZE + Self::ITEM_SIZE * idx; + let end = start + Self::ITEM_SIZE; + WithdrawalCotaNFTKeyV1::new_unchecked(self.0.slice(start..end)) + } + + pub fn as_reader<'r>(&'r self) -> WithdrawalCotaNFTKeyV1VecReader<'r> { + WithdrawalCotaNFTKeyV1VecReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for WithdrawalCotaNFTKeyV1Vec { + type Builder = WithdrawalCotaNFTKeyV1VecBuilder; + + const NAME: &'static str = "WithdrawalCotaNFTKeyV1Vec"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + WithdrawalCotaNFTKeyV1Vec(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTKeyV1VecReader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTKeyV1VecReader::from_compatible_slice(slice) + .map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder().extend(self.into_iter()) + } +} +#[derive(Clone, Copy)] +pub struct WithdrawalCotaNFTKeyV1VecReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for WithdrawalCotaNFTKeyV1VecReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for WithdrawalCotaNFTKeyV1VecReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for WithdrawalCotaNFTKeyV1VecReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + for i in 0..self.len() { + if i == 0 { + write!(f, "{}", self.get_unchecked(i))?; + } else { + write!(f, ", {}", self.get_unchecked(i))?; + } + } + write!(f, "]") + } +} +impl<'r> WithdrawalCotaNFTKeyV1VecReader<'r> { + pub const ITEM_SIZE: usize = 50; + + pub fn total_size(&self) -> usize { + molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.item_count() + } + + pub fn item_count(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn len(&self) -> usize { + self.item_count() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn get(&self, idx: usize) -> Option> { + if idx >= self.len() { + None + } else { + Some(self.get_unchecked(idx)) + } + } + + pub fn get_unchecked(&self, idx: usize) -> WithdrawalCotaNFTKeyV1Reader<'r> { + let start = molecule::NUMBER_SIZE + Self::ITEM_SIZE * idx; + let end = start + Self::ITEM_SIZE; + WithdrawalCotaNFTKeyV1Reader::new_unchecked(&self.as_slice()[start..end]) + } +} +impl<'r> molecule::prelude::Reader<'r> for WithdrawalCotaNFTKeyV1VecReader<'r> { + type Entity = WithdrawalCotaNFTKeyV1Vec; + + const NAME: &'static str = "WithdrawalCotaNFTKeyV1VecReader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + WithdrawalCotaNFTKeyV1VecReader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let item_count = molecule::unpack_number(slice) as usize; + if item_count == 0 { + if slice_len != molecule::NUMBER_SIZE { + return ve!(Self, TotalSizeNotMatch, molecule::NUMBER_SIZE, slice_len); + } + return Ok(()); + } + let total_size = molecule::NUMBER_SIZE + Self::ITEM_SIZE * item_count; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct WithdrawalCotaNFTKeyV1VecBuilder(pub(crate) Vec); +impl WithdrawalCotaNFTKeyV1VecBuilder { + pub const ITEM_SIZE: usize = 50; + + pub fn set(mut self, v: Vec) -> Self { + self.0 = v; + self + } + + pub fn push(mut self, v: WithdrawalCotaNFTKeyV1) -> Self { + self.0.push(v); + self + } + + pub fn extend>( + mut self, + iter: T, + ) -> Self { + for elem in iter { + self.0.push(elem); + } + self + } + + pub fn replace( + &mut self, + index: usize, + v: WithdrawalCotaNFTKeyV1, + ) -> Option { + self.0 + .get_mut(index) + .map(|item| ::core::mem::replace(item, v)) + } +} +impl molecule::prelude::Builder for WithdrawalCotaNFTKeyV1VecBuilder { + type Entity = WithdrawalCotaNFTKeyV1Vec; + + const NAME: &'static str = "WithdrawalCotaNFTKeyV1VecBuilder"; + + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE + Self::ITEM_SIZE * self.0.len() + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(&molecule::pack_number(self.0.len() as molecule::Number))?; + for inner in &self.0[..] { + writer.write_all(inner.as_slice())?; + } + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + WithdrawalCotaNFTKeyV1Vec::new_unchecked(inner.into()) + } +} +pub struct WithdrawalCotaNFTKeyV1VecIterator(WithdrawalCotaNFTKeyV1Vec, usize, usize); +impl ::core::iter::Iterator for WithdrawalCotaNFTKeyV1VecIterator { + type Item = WithdrawalCotaNFTKeyV1; + + fn next(&mut self) -> Option { + if self.1 >= self.2 { + None + } else { + let ret = self.0.get_unchecked(self.1); + self.1 += 1; + Some(ret) + } + } +} +impl ::core::iter::ExactSizeIterator for WithdrawalCotaNFTKeyV1VecIterator { + fn len(&self) -> usize { + self.2 - self.1 + } +} +impl ::core::iter::IntoIterator for WithdrawalCotaNFTKeyV1Vec { + type IntoIter = WithdrawalCotaNFTKeyV1VecIterator; + type Item = WithdrawalCotaNFTKeyV1; + + fn into_iter(self) -> Self::IntoIter { + let len = self.len(); + WithdrawalCotaNFTKeyV1VecIterator(self, 0, len) + } +} +impl<'r> WithdrawalCotaNFTKeyV1VecReader<'r> { + pub fn iter<'t>(&'t self) -> WithdrawalCotaNFTKeyV1VecReaderIterator<'t, 'r> { + WithdrawalCotaNFTKeyV1VecReaderIterator(&self, 0, self.len()) + } +} +pub struct WithdrawalCotaNFTKeyV1VecReaderIterator<'t, 'r>( + &'t WithdrawalCotaNFTKeyV1VecReader<'r>, + usize, + usize, +); +impl<'t: 'r, 'r> ::core::iter::Iterator for WithdrawalCotaNFTKeyV1VecReaderIterator<'t, 'r> { + type Item = WithdrawalCotaNFTKeyV1Reader<'t>; + + fn next(&mut self) -> Option { + if self.1 >= self.2 { + None + } else { + let ret = self.0.get_unchecked(self.1); + self.1 += 1; + Some(ret) + } + } +} +impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator + for WithdrawalCotaNFTKeyV1VecReaderIterator<'t, 'r> +{ + fn len(&self) -> usize { + self.2 - self.1 + } +} +#[derive(Clone)] +pub struct WithdrawalCotaNFTValueV1(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for WithdrawalCotaNFTValueV1 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for WithdrawalCotaNFTValueV1 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for WithdrawalCotaNFTValueV1 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "nft_info", self.nft_info())?; + write!(f, ", {}: {}", "to_lock", self.to_lock())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for WithdrawalCotaNFTValueV1 { + fn default() -> Self { + let v: Vec = vec![ + 38, 0, 0, 0, 12, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + WithdrawalCotaNFTValueV1::new_unchecked(v.into()) + } +} +impl WithdrawalCotaNFTValueV1 { + pub const FIELD_COUNT: usize = 2; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn nft_info(&self) -> CotaNFTInfo { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + CotaNFTInfo::new_unchecked(self.0.slice(start..end)) + } + + pub fn to_lock(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } else { + Bytes::new_unchecked(self.0.slice(start..)) + } + } + + pub fn as_reader<'r>(&'r self) -> WithdrawalCotaNFTValueV1Reader<'r> { + WithdrawalCotaNFTValueV1Reader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for WithdrawalCotaNFTValueV1 { + type Builder = WithdrawalCotaNFTValueV1Builder; + + const NAME: &'static str = "WithdrawalCotaNFTValueV1"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + WithdrawalCotaNFTValueV1(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTValueV1Reader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTValueV1Reader::from_compatible_slice(slice) + .map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .nft_info(self.nft_info()) + .to_lock(self.to_lock()) + } +} +#[derive(Clone, Copy)] +pub struct WithdrawalCotaNFTValueV1Reader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for WithdrawalCotaNFTValueV1Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for WithdrawalCotaNFTValueV1Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for WithdrawalCotaNFTValueV1Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "nft_info", self.nft_info())?; + write!(f, ", {}: {}", "to_lock", self.to_lock())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> WithdrawalCotaNFTValueV1Reader<'r> { + pub const FIELD_COUNT: usize = 2; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn nft_info(&self) -> CotaNFTInfoReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + CotaNFTInfoReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn to_lock(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BytesReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for WithdrawalCotaNFTValueV1Reader<'r> { + type Entity = WithdrawalCotaNFTValueV1; + + const NAME: &'static str = "WithdrawalCotaNFTValueV1Reader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + WithdrawalCotaNFTValueV1Reader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + CotaNFTInfoReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + BytesReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct WithdrawalCotaNFTValueV1Builder { + pub(crate) nft_info: CotaNFTInfo, + pub(crate) to_lock: Bytes, +} +impl WithdrawalCotaNFTValueV1Builder { + pub const FIELD_COUNT: usize = 2; + + pub fn nft_info(mut self, v: CotaNFTInfo) -> Self { + self.nft_info = v; + self + } + + pub fn to_lock(mut self, v: Bytes) -> Self { + self.to_lock = v; + self + } +} +impl molecule::prelude::Builder for WithdrawalCotaNFTValueV1Builder { + type Entity = WithdrawalCotaNFTValueV1; + + const NAME: &'static str = "WithdrawalCotaNFTValueV1Builder"; + + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.nft_info.as_slice().len() + + self.to_lock.as_slice().len() + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.nft_info.as_slice().len(); + offsets.push(total_size); + total_size += self.to_lock.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.nft_info.as_slice())?; + writer.write_all(self.to_lock.as_slice())?; + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + WithdrawalCotaNFTValueV1::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct WithdrawalCotaNFTValueV1Vec(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for WithdrawalCotaNFTValueV1Vec { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for WithdrawalCotaNFTValueV1Vec { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for WithdrawalCotaNFTValueV1Vec { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + for i in 0..self.len() { + if i == 0 { + write!(f, "{}", self.get_unchecked(i))?; + } else { + write!(f, ", {}", self.get_unchecked(i))?; + } + } + write!(f, "]") + } +} +impl ::core::default::Default for WithdrawalCotaNFTValueV1Vec { + fn default() -> Self { + let v: Vec = vec![4, 0, 0, 0]; + WithdrawalCotaNFTValueV1Vec::new_unchecked(v.into()) + } +} +impl WithdrawalCotaNFTValueV1Vec { + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn item_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn len(&self) -> usize { + self.item_count() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn get(&self, idx: usize) -> Option { + if idx >= self.len() { + None + } else { + Some(self.get_unchecked(idx)) + } + } + + pub fn get_unchecked(&self, idx: usize) -> WithdrawalCotaNFTValueV1 { + let slice = self.as_slice(); + let start_idx = molecule::NUMBER_SIZE * (1 + idx); + let start = molecule::unpack_number(&slice[start_idx..]) as usize; + if idx == self.len() - 1 { + WithdrawalCotaNFTValueV1::new_unchecked(self.0.slice(start..)) + } else { + let end_idx = start_idx + molecule::NUMBER_SIZE; + let end = molecule::unpack_number(&slice[end_idx..]) as usize; + WithdrawalCotaNFTValueV1::new_unchecked(self.0.slice(start..end)) + } + } + + pub fn as_reader<'r>(&'r self) -> WithdrawalCotaNFTValueV1VecReader<'r> { + WithdrawalCotaNFTValueV1VecReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for WithdrawalCotaNFTValueV1Vec { + type Builder = WithdrawalCotaNFTValueV1VecBuilder; + + const NAME: &'static str = "WithdrawalCotaNFTValueV1Vec"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + WithdrawalCotaNFTValueV1Vec(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTValueV1VecReader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTValueV1VecReader::from_compatible_slice(slice) + .map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder().extend(self.into_iter()) + } +} +#[derive(Clone, Copy)] +pub struct WithdrawalCotaNFTValueV1VecReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for WithdrawalCotaNFTValueV1VecReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for WithdrawalCotaNFTValueV1VecReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for WithdrawalCotaNFTValueV1VecReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} [", Self::NAME)?; + for i in 0..self.len() { + if i == 0 { + write!(f, "{}", self.get_unchecked(i))?; + } else { + write!(f, ", {}", self.get_unchecked(i))?; + } + } + write!(f, "]") + } +} +impl<'r> WithdrawalCotaNFTValueV1VecReader<'r> { + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn item_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn len(&self) -> usize { + self.item_count() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn get(&self, idx: usize) -> Option> { + if idx >= self.len() { + None + } else { + Some(self.get_unchecked(idx)) + } + } + + pub fn get_unchecked(&self, idx: usize) -> WithdrawalCotaNFTValueV1Reader<'r> { + let slice = self.as_slice(); + let start_idx = molecule::NUMBER_SIZE * (1 + idx); + let start = molecule::unpack_number(&slice[start_idx..]) as usize; + if idx == self.len() - 1 { + WithdrawalCotaNFTValueV1Reader::new_unchecked(&self.as_slice()[start..]) + } else { + let end_idx = start_idx + molecule::NUMBER_SIZE; + let end = molecule::unpack_number(&slice[end_idx..]) as usize; + WithdrawalCotaNFTValueV1Reader::new_unchecked(&self.as_slice()[start..end]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for WithdrawalCotaNFTValueV1VecReader<'r> { + type Entity = WithdrawalCotaNFTValueV1Vec; + + const NAME: &'static str = "WithdrawalCotaNFTValueV1VecReader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + WithdrawalCotaNFTValueV1VecReader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!( + Self, + TotalSizeNotMatch, + molecule::NUMBER_SIZE * 2, + slice_len + ); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + for pair in offsets.windows(2) { + let start = pair[0]; + let end = pair[1]; + WithdrawalCotaNFTValueV1Reader::verify(&slice[start..end], compatible)?; + } + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct WithdrawalCotaNFTValueV1VecBuilder(pub(crate) Vec); +impl WithdrawalCotaNFTValueV1VecBuilder { + pub fn set(mut self, v: Vec) -> Self { + self.0 = v; + self + } + + pub fn push(mut self, v: WithdrawalCotaNFTValueV1) -> Self { + self.0.push(v); + self + } + + pub fn extend>( + mut self, + iter: T, + ) -> Self { + for elem in iter { + self.0.push(elem); + } + self + } + + pub fn replace( + &mut self, + index: usize, + v: WithdrawalCotaNFTValueV1, + ) -> Option { + self.0 + .get_mut(index) + .map(|item| ::core::mem::replace(item, v)) + } +} +impl molecule::prelude::Builder for WithdrawalCotaNFTValueV1VecBuilder { + type Entity = WithdrawalCotaNFTValueV1Vec; + + const NAME: &'static str = "WithdrawalCotaNFTValueV1VecBuilder"; + + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (self.0.len() + 1) + + self + .0 + .iter() + .map(|inner| inner.as_slice().len()) + .sum::() + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let item_count = self.0.len(); + if item_count == 0 { + writer.write_all(&molecule::pack_number( + molecule::NUMBER_SIZE as molecule::Number, + ))?; + } else { + let (total_size, offsets) = self.0.iter().fold( + ( + molecule::NUMBER_SIZE * (item_count + 1), + Vec::with_capacity(item_count), + ), + |(start, mut offsets), inner| { + offsets.push(start); + (start + inner.as_slice().len(), offsets) + }, + ); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + for inner in self.0.iter() { + writer.write_all(inner.as_slice())?; + } + } + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + WithdrawalCotaNFTValueV1Vec::new_unchecked(inner.into()) + } +} +pub struct WithdrawalCotaNFTValueV1VecIterator(WithdrawalCotaNFTValueV1Vec, usize, usize); +impl ::core::iter::Iterator for WithdrawalCotaNFTValueV1VecIterator { + type Item = WithdrawalCotaNFTValueV1; + + fn next(&mut self) -> Option { + if self.1 >= self.2 { + None + } else { + let ret = self.0.get_unchecked(self.1); + self.1 += 1; + Some(ret) + } + } +} +impl ::core::iter::ExactSizeIterator for WithdrawalCotaNFTValueV1VecIterator { + fn len(&self) -> usize { + self.2 - self.1 + } +} +impl ::core::iter::IntoIterator for WithdrawalCotaNFTValueV1Vec { + type IntoIter = WithdrawalCotaNFTValueV1VecIterator; + type Item = WithdrawalCotaNFTValueV1; + + fn into_iter(self) -> Self::IntoIter { + let len = self.len(); + WithdrawalCotaNFTValueV1VecIterator(self, 0, len) + } +} +impl<'r> WithdrawalCotaNFTValueV1VecReader<'r> { + pub fn iter<'t>(&'t self) -> WithdrawalCotaNFTValueV1VecReaderIterator<'t, 'r> { + WithdrawalCotaNFTValueV1VecReaderIterator(&self, 0, self.len()) + } +} +pub struct WithdrawalCotaNFTValueV1VecReaderIterator<'t, 'r>( + &'t WithdrawalCotaNFTValueV1VecReader<'r>, + usize, + usize, +); +impl<'t: 'r, 'r> ::core::iter::Iterator for WithdrawalCotaNFTValueV1VecReaderIterator<'t, 'r> { + type Item = WithdrawalCotaNFTValueV1Reader<'t>; + + fn next(&mut self) -> Option { + if self.1 >= self.2 { + None + } else { + let ret = self.0.get_unchecked(self.1); + self.1 += 1; + Some(ret) + } + } +} +impl<'t: 'r, 'r> ::core::iter::ExactSizeIterator + for WithdrawalCotaNFTValueV1VecReaderIterator<'t, 'r> +{ + fn len(&self) -> usize { + self.2 - self.1 + } +} diff --git a/src/define.mol b/src/define.mol index 39dc2c6..ab7d50e 100644 --- a/src/define.mol +++ b/src/define.mol @@ -5,4 +5,4 @@ table DefineCotaNFTEntries { define_values: DefineCotaNFTValueVec, proof: Bytes, action: Bytes, -} \ No newline at end of file +} diff --git a/src/define.rs b/src/define.rs index 20ba433..02e6659 100644 --- a/src/define.rs +++ b/src/define.rs @@ -9,7 +9,6 @@ use super::molecule::{self, prelude::*}; extern crate alloc; pub use alloc::vec::*; // these lines above are manually added -// replace "::molecule" to "molecule" in below code use super::common::*; use molecule::prelude::*; diff --git a/src/mint.mol b/src/mint.mol index 7c4b4c3..d8b19d8 100644 --- a/src/mint.mol +++ b/src/mint.mol @@ -8,4 +8,15 @@ table MintCotaNFTEntries { withdrawal_values: WithdrawalCotaNFTValueVec, proof: Bytes, action: Bytes, -} \ No newline at end of file +} + +// V1 +table MintCotaNFTV1Entries { + define_keys: DefineCotaNFTKeyVec, + define_old_values: DefineCotaNFTValueVec, + define_new_values: DefineCotaNFTValueVec, + withdrawal_keys: WithdrawalCotaNFTKeyV1Vec, + withdrawal_values: WithdrawalCotaNFTValueV1Vec, + proof: Bytes, + action: Bytes, +} diff --git a/src/mint.rs b/src/mint.rs index 00e3a51..d88c048 100644 --- a/src/mint.rs +++ b/src/mint.rs @@ -1,4 +1,4 @@ -// Generated by Molecule 0.7.2 +// Generated by Molecule 0.7.3 #![allow(unused_imports)] #![allow(dead_code)] @@ -9,7 +9,6 @@ use super::molecule::{self, prelude::*}; extern crate alloc; pub use alloc::vec::*; // these lines above are manually added -// replace "::molecule" to "molecule" in below code use super::common::*; use molecule::prelude::*; @@ -50,7 +49,7 @@ impl ::core::default::Default for MintCotaNFTEntries { fn default() -> Self { let v: Vec = vec![ 60, 0, 0, 0, 32, 0, 0, 0, 36, 0, 0, 0, 40, 0, 0, 0, 44, 0, 0, 0, 48, 0, 0, 0, 52, 0, 0, - 0, 56, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; MintCotaNFTEntries::new_unchecked(v.into()) @@ -451,3 +450,441 @@ impl molecule::prelude::Builder for MintCotaNFTEntriesBuilder { MintCotaNFTEntries::new_unchecked(inner.into()) } } +#[derive(Clone)] +pub struct MintCotaNFTV1Entries(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for MintCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for MintCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for MintCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "define_keys", self.define_keys())?; + write!(f, ", {}: {}", "define_old_values", self.define_old_values())?; + write!(f, ", {}: {}", "define_new_values", self.define_new_values())?; + write!(f, ", {}: {}", "withdrawal_keys", self.withdrawal_keys())?; + write!(f, ", {}: {}", "withdrawal_values", self.withdrawal_values())?; + write!(f, ", {}: {}", "proof", self.proof())?; + write!(f, ", {}: {}", "action", self.action())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for MintCotaNFTV1Entries { + fn default() -> Self { + let v: Vec = vec![ + 60, 0, 0, 0, 32, 0, 0, 0, 36, 0, 0, 0, 40, 0, 0, 0, 44, 0, 0, 0, 48, 0, 0, 0, 52, 0, 0, + 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]; + MintCotaNFTV1Entries::new_unchecked(v.into()) + } +} +impl MintCotaNFTV1Entries { + pub const FIELD_COUNT: usize = 7; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn define_keys(&self) -> DefineCotaNFTKeyVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + DefineCotaNFTKeyVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn define_old_values(&self) -> DefineCotaNFTValueVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + DefineCotaNFTValueVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn define_new_values(&self) -> DefineCotaNFTValueVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + DefineCotaNFTValueVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_keys(&self) -> WithdrawalCotaNFTKeyV1Vec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + WithdrawalCotaNFTKeyV1Vec::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_values(&self) -> WithdrawalCotaNFTValueV1Vec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + WithdrawalCotaNFTValueV1Vec::new_unchecked(self.0.slice(start..end)) + } + + pub fn proof(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } + + pub fn action(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } else { + Bytes::new_unchecked(self.0.slice(start..)) + } + } + + pub fn as_reader<'r>(&'r self) -> MintCotaNFTV1EntriesReader<'r> { + MintCotaNFTV1EntriesReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for MintCotaNFTV1Entries { + type Builder = MintCotaNFTV1EntriesBuilder; + + const NAME: &'static str = "MintCotaNFTV1Entries"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + MintCotaNFTV1Entries(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + MintCotaNFTV1EntriesReader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + MintCotaNFTV1EntriesReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .define_keys(self.define_keys()) + .define_old_values(self.define_old_values()) + .define_new_values(self.define_new_values()) + .withdrawal_keys(self.withdrawal_keys()) + .withdrawal_values(self.withdrawal_values()) + .proof(self.proof()) + .action(self.action()) + } +} +#[derive(Clone, Copy)] +pub struct MintCotaNFTV1EntriesReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for MintCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for MintCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for MintCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "define_keys", self.define_keys())?; + write!(f, ", {}: {}", "define_old_values", self.define_old_values())?; + write!(f, ", {}: {}", "define_new_values", self.define_new_values())?; + write!(f, ", {}: {}", "withdrawal_keys", self.withdrawal_keys())?; + write!(f, ", {}: {}", "withdrawal_values", self.withdrawal_values())?; + write!(f, ", {}: {}", "proof", self.proof())?; + write!(f, ", {}: {}", "action", self.action())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> MintCotaNFTV1EntriesReader<'r> { + pub const FIELD_COUNT: usize = 7; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn define_keys(&self) -> DefineCotaNFTKeyVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + DefineCotaNFTKeyVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn define_old_values(&self) -> DefineCotaNFTValueVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + DefineCotaNFTValueVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn define_new_values(&self) -> DefineCotaNFTValueVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + DefineCotaNFTValueVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_keys(&self) -> WithdrawalCotaNFTKeyV1VecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + WithdrawalCotaNFTKeyV1VecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_values(&self) -> WithdrawalCotaNFTValueV1VecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + WithdrawalCotaNFTValueV1VecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn proof(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn action(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BytesReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for MintCotaNFTV1EntriesReader<'r> { + type Entity = MintCotaNFTV1Entries; + + const NAME: &'static str = "MintCotaNFTV1EntriesReader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + MintCotaNFTV1EntriesReader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + DefineCotaNFTKeyVecReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + DefineCotaNFTValueVecReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + DefineCotaNFTValueVecReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + WithdrawalCotaNFTKeyV1VecReader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + WithdrawalCotaNFTValueV1VecReader::verify(&slice[offsets[4]..offsets[5]], compatible)?; + BytesReader::verify(&slice[offsets[5]..offsets[6]], compatible)?; + BytesReader::verify(&slice[offsets[6]..offsets[7]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct MintCotaNFTV1EntriesBuilder { + pub(crate) define_keys: DefineCotaNFTKeyVec, + pub(crate) define_old_values: DefineCotaNFTValueVec, + pub(crate) define_new_values: DefineCotaNFTValueVec, + pub(crate) withdrawal_keys: WithdrawalCotaNFTKeyV1Vec, + pub(crate) withdrawal_values: WithdrawalCotaNFTValueV1Vec, + pub(crate) proof: Bytes, + pub(crate) action: Bytes, +} +impl MintCotaNFTV1EntriesBuilder { + pub const FIELD_COUNT: usize = 7; + + pub fn define_keys(mut self, v: DefineCotaNFTKeyVec) -> Self { + self.define_keys = v; + self + } + + pub fn define_old_values(mut self, v: DefineCotaNFTValueVec) -> Self { + self.define_old_values = v; + self + } + + pub fn define_new_values(mut self, v: DefineCotaNFTValueVec) -> Self { + self.define_new_values = v; + self + } + + pub fn withdrawal_keys(mut self, v: WithdrawalCotaNFTKeyV1Vec) -> Self { + self.withdrawal_keys = v; + self + } + + pub fn withdrawal_values(mut self, v: WithdrawalCotaNFTValueV1Vec) -> Self { + self.withdrawal_values = v; + self + } + + pub fn proof(mut self, v: Bytes) -> Self { + self.proof = v; + self + } + + pub fn action(mut self, v: Bytes) -> Self { + self.action = v; + self + } +} +impl molecule::prelude::Builder for MintCotaNFTV1EntriesBuilder { + type Entity = MintCotaNFTV1Entries; + + const NAME: &'static str = "MintCotaNFTV1EntriesBuilder"; + + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.define_keys.as_slice().len() + + self.define_old_values.as_slice().len() + + self.define_new_values.as_slice().len() + + self.withdrawal_keys.as_slice().len() + + self.withdrawal_values.as_slice().len() + + self.proof.as_slice().len() + + self.action.as_slice().len() + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.define_keys.as_slice().len(); + offsets.push(total_size); + total_size += self.define_old_values.as_slice().len(); + offsets.push(total_size); + total_size += self.define_new_values.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_keys.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_values.as_slice().len(); + offsets.push(total_size); + total_size += self.proof.as_slice().len(); + offsets.push(total_size); + total_size += self.action.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.define_keys.as_slice())?; + writer.write_all(self.define_old_values.as_slice())?; + writer.write_all(self.define_new_values.as_slice())?; + writer.write_all(self.withdrawal_keys.as_slice())?; + writer.write_all(self.withdrawal_values.as_slice())?; + writer.write_all(self.proof.as_slice())?; + writer.write_all(self.action.as_slice())?; + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + MintCotaNFTV1Entries::new_unchecked(inner.into()) + } +} diff --git a/src/registry.mol b/src/registry.mol index d5b07bb..77f7be1 100644 --- a/src/registry.mol +++ b/src/registry.mol @@ -10,4 +10,4 @@ vector RegistryVec ; table CotaNFTRegistryEntries { registries: RegistryVec, proof: Bytes, -} \ No newline at end of file +} diff --git a/src/registry.rs b/src/registry.rs index 253e9d1..1e19d7b 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -9,7 +9,6 @@ use super::molecule::{self, prelude::*}; extern crate alloc; pub use alloc::vec::*; // these lines above are manually added -// replace "::molecule" to "molecule" in below code use super::common::*; use molecule::prelude::*; diff --git a/src/transfer.mol b/src/transfer.mol index 27a1adf..402d19e 100644 --- a/src/transfer.mol +++ b/src/transfer.mol @@ -27,4 +27,24 @@ table TransferCotaNFTEntries { proof: Bytes, withdrawal_proof: Bytes, action: Bytes, -} \ No newline at end of file +} + +// V1 +table WithdrawalCotaNFTV1Entries { + hold_keys: HoldCotaNFTKeyVec, + hold_values: HoldCotaNFTValueVec, + withdrawal_keys: WithdrawalCotaNFTKeyV1Vec, + withdrawal_values: WithdrawalCotaNFTValueV1Vec, + proof: Bytes, + action: Bytes, +} + +table TransferCotaNFTV1Entries { + claim_keys: ClaimCotaNFTKeyVec, + claim_values: ClaimCotaNFTValueVec, + withdrawal_keys: WithdrawalCotaNFTKeyV1Vec, + withdrawal_values: WithdrawalCotaNFTValueV1Vec, + proof: Bytes, + withdrawal_proof: Bytes, + action: Bytes, +} diff --git a/src/transfer.rs b/src/transfer.rs index 616ee6d..5e36327 100644 --- a/src/transfer.rs +++ b/src/transfer.rs @@ -1,4 +1,4 @@ -// Generated by Molecule 0.7.2 +// Generated by Molecule 0.7.3 #![allow(unused_imports)] #![allow(dead_code)] @@ -9,7 +9,6 @@ use super::molecule::{self, prelude::*}; extern crate alloc; pub use alloc::vec::*; // these lines above are manually added -// replace "::molecule" to "molecule" in below code use super::common::*; use molecule::prelude::*; @@ -460,7 +459,7 @@ impl ::core::default::Default for ClaimCotaNFTEntries { fn default() -> Self { let v: Vec = vec![ 60, 0, 0, 0, 32, 0, 0, 0, 36, 0, 0, 0, 40, 0, 0, 0, 44, 0, 0, 0, 48, 0, 0, 0, 52, 0, 0, - 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; ClaimCotaNFTEntries::new_unchecked(v.into()) @@ -898,7 +897,7 @@ impl ::core::default::Default for TransferCotaNFTEntries { fn default() -> Self { let v: Vec = vec![ 60, 0, 0, 0, 32, 0, 0, 0, 36, 0, 0, 0, 40, 0, 0, 0, 44, 0, 0, 0, 48, 0, 0, 0, 52, 0, 0, - 0, 56, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; TransferCotaNFTEntries::new_unchecked(v.into()) @@ -1299,3 +1298,852 @@ impl molecule::prelude::Builder for TransferCotaNFTEntriesBuilder { TransferCotaNFTEntries::new_unchecked(inner.into()) } } +#[derive(Clone)] +pub struct WithdrawalCotaNFTV1Entries(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for WithdrawalCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for WithdrawalCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for WithdrawalCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "hold_keys", self.hold_keys())?; + write!(f, ", {}: {}", "hold_values", self.hold_values())?; + write!(f, ", {}: {}", "withdrawal_keys", self.withdrawal_keys())?; + write!(f, ", {}: {}", "withdrawal_values", self.withdrawal_values())?; + write!(f, ", {}: {}", "proof", self.proof())?; + write!(f, ", {}: {}", "action", self.action())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for WithdrawalCotaNFTV1Entries { + fn default() -> Self { + let v: Vec = vec![ + 52, 0, 0, 0, 28, 0, 0, 0, 32, 0, 0, 0, 36, 0, 0, 0, 40, 0, 0, 0, 44, 0, 0, 0, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + WithdrawalCotaNFTV1Entries::new_unchecked(v.into()) + } +} +impl WithdrawalCotaNFTV1Entries { + pub const FIELD_COUNT: usize = 6; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn hold_keys(&self) -> HoldCotaNFTKeyVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + HoldCotaNFTKeyVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn hold_values(&self) -> HoldCotaNFTValueVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + HoldCotaNFTValueVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_keys(&self) -> WithdrawalCotaNFTKeyV1Vec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + WithdrawalCotaNFTKeyV1Vec::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_values(&self) -> WithdrawalCotaNFTValueV1Vec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + WithdrawalCotaNFTValueV1Vec::new_unchecked(self.0.slice(start..end)) + } + + pub fn proof(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } + + pub fn action(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[28..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } else { + Bytes::new_unchecked(self.0.slice(start..)) + } + } + + pub fn as_reader<'r>(&'r self) -> WithdrawalCotaNFTV1EntriesReader<'r> { + WithdrawalCotaNFTV1EntriesReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for WithdrawalCotaNFTV1Entries { + type Builder = WithdrawalCotaNFTV1EntriesBuilder; + + const NAME: &'static str = "WithdrawalCotaNFTV1Entries"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + WithdrawalCotaNFTV1Entries(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTV1EntriesReader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + WithdrawalCotaNFTV1EntriesReader::from_compatible_slice(slice) + .map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .hold_keys(self.hold_keys()) + .hold_values(self.hold_values()) + .withdrawal_keys(self.withdrawal_keys()) + .withdrawal_values(self.withdrawal_values()) + .proof(self.proof()) + .action(self.action()) + } +} +#[derive(Clone, Copy)] +pub struct WithdrawalCotaNFTV1EntriesReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for WithdrawalCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for WithdrawalCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for WithdrawalCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "hold_keys", self.hold_keys())?; + write!(f, ", {}: {}", "hold_values", self.hold_values())?; + write!(f, ", {}: {}", "withdrawal_keys", self.withdrawal_keys())?; + write!(f, ", {}: {}", "withdrawal_values", self.withdrawal_values())?; + write!(f, ", {}: {}", "proof", self.proof())?; + write!(f, ", {}: {}", "action", self.action())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> WithdrawalCotaNFTV1EntriesReader<'r> { + pub const FIELD_COUNT: usize = 6; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn hold_keys(&self) -> HoldCotaNFTKeyVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + HoldCotaNFTKeyVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn hold_values(&self) -> HoldCotaNFTValueVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + HoldCotaNFTValueVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_keys(&self) -> WithdrawalCotaNFTKeyV1VecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + WithdrawalCotaNFTKeyV1VecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_values(&self) -> WithdrawalCotaNFTValueV1VecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + WithdrawalCotaNFTValueV1VecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn proof(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn action(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[28..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BytesReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for WithdrawalCotaNFTV1EntriesReader<'r> { + type Entity = WithdrawalCotaNFTV1Entries; + + const NAME: &'static str = "WithdrawalCotaNFTV1EntriesReader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + WithdrawalCotaNFTV1EntriesReader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + HoldCotaNFTKeyVecReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + HoldCotaNFTValueVecReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + WithdrawalCotaNFTKeyV1VecReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + WithdrawalCotaNFTValueV1VecReader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + BytesReader::verify(&slice[offsets[4]..offsets[5]], compatible)?; + BytesReader::verify(&slice[offsets[5]..offsets[6]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct WithdrawalCotaNFTV1EntriesBuilder { + pub(crate) hold_keys: HoldCotaNFTKeyVec, + pub(crate) hold_values: HoldCotaNFTValueVec, + pub(crate) withdrawal_keys: WithdrawalCotaNFTKeyV1Vec, + pub(crate) withdrawal_values: WithdrawalCotaNFTValueV1Vec, + pub(crate) proof: Bytes, + pub(crate) action: Bytes, +} +impl WithdrawalCotaNFTV1EntriesBuilder { + pub const FIELD_COUNT: usize = 6; + + pub fn hold_keys(mut self, v: HoldCotaNFTKeyVec) -> Self { + self.hold_keys = v; + self + } + + pub fn hold_values(mut self, v: HoldCotaNFTValueVec) -> Self { + self.hold_values = v; + self + } + + pub fn withdrawal_keys(mut self, v: WithdrawalCotaNFTKeyV1Vec) -> Self { + self.withdrawal_keys = v; + self + } + + pub fn withdrawal_values(mut self, v: WithdrawalCotaNFTValueV1Vec) -> Self { + self.withdrawal_values = v; + self + } + + pub fn proof(mut self, v: Bytes) -> Self { + self.proof = v; + self + } + + pub fn action(mut self, v: Bytes) -> Self { + self.action = v; + self + } +} +impl molecule::prelude::Builder for WithdrawalCotaNFTV1EntriesBuilder { + type Entity = WithdrawalCotaNFTV1Entries; + + const NAME: &'static str = "WithdrawalCotaNFTV1EntriesBuilder"; + + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.hold_keys.as_slice().len() + + self.hold_values.as_slice().len() + + self.withdrawal_keys.as_slice().len() + + self.withdrawal_values.as_slice().len() + + self.proof.as_slice().len() + + self.action.as_slice().len() + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.hold_keys.as_slice().len(); + offsets.push(total_size); + total_size += self.hold_values.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_keys.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_values.as_slice().len(); + offsets.push(total_size); + total_size += self.proof.as_slice().len(); + offsets.push(total_size); + total_size += self.action.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.hold_keys.as_slice())?; + writer.write_all(self.hold_values.as_slice())?; + writer.write_all(self.withdrawal_keys.as_slice())?; + writer.write_all(self.withdrawal_values.as_slice())?; + writer.write_all(self.proof.as_slice())?; + writer.write_all(self.action.as_slice())?; + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + WithdrawalCotaNFTV1Entries::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct TransferCotaNFTV1Entries(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for TransferCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for TransferCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for TransferCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "claim_keys", self.claim_keys())?; + write!(f, ", {}: {}", "claim_values", self.claim_values())?; + write!(f, ", {}: {}", "withdrawal_keys", self.withdrawal_keys())?; + write!(f, ", {}: {}", "withdrawal_values", self.withdrawal_values())?; + write!(f, ", {}: {}", "proof", self.proof())?; + write!(f, ", {}: {}", "withdrawal_proof", self.withdrawal_proof())?; + write!(f, ", {}: {}", "action", self.action())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for TransferCotaNFTV1Entries { + fn default() -> Self { + let v: Vec = vec![ + 60, 0, 0, 0, 32, 0, 0, 0, 36, 0, 0, 0, 40, 0, 0, 0, 44, 0, 0, 0, 48, 0, 0, 0, 52, 0, 0, + 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]; + TransferCotaNFTV1Entries::new_unchecked(v.into()) + } +} +impl TransferCotaNFTV1Entries { + pub const FIELD_COUNT: usize = 7; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn claim_keys(&self) -> ClaimCotaNFTKeyVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ClaimCotaNFTKeyVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn claim_values(&self) -> ClaimCotaNFTValueVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + ClaimCotaNFTValueVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_keys(&self) -> WithdrawalCotaNFTKeyV1Vec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + WithdrawalCotaNFTKeyV1Vec::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_values(&self) -> WithdrawalCotaNFTValueV1Vec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + WithdrawalCotaNFTValueV1Vec::new_unchecked(self.0.slice(start..end)) + } + + pub fn proof(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_proof(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } + + pub fn action(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } else { + Bytes::new_unchecked(self.0.slice(start..)) + } + } + + pub fn as_reader<'r>(&'r self) -> TransferCotaNFTV1EntriesReader<'r> { + TransferCotaNFTV1EntriesReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for TransferCotaNFTV1Entries { + type Builder = TransferCotaNFTV1EntriesBuilder; + + const NAME: &'static str = "TransferCotaNFTV1Entries"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + TransferCotaNFTV1Entries(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TransferCotaNFTV1EntriesReader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TransferCotaNFTV1EntriesReader::from_compatible_slice(slice) + .map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .claim_keys(self.claim_keys()) + .claim_values(self.claim_values()) + .withdrawal_keys(self.withdrawal_keys()) + .withdrawal_values(self.withdrawal_values()) + .proof(self.proof()) + .withdrawal_proof(self.withdrawal_proof()) + .action(self.action()) + } +} +#[derive(Clone, Copy)] +pub struct TransferCotaNFTV1EntriesReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for TransferCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for TransferCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for TransferCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "claim_keys", self.claim_keys())?; + write!(f, ", {}: {}", "claim_values", self.claim_values())?; + write!(f, ", {}: {}", "withdrawal_keys", self.withdrawal_keys())?; + write!(f, ", {}: {}", "withdrawal_values", self.withdrawal_values())?; + write!(f, ", {}: {}", "proof", self.proof())?; + write!(f, ", {}: {}", "withdrawal_proof", self.withdrawal_proof())?; + write!(f, ", {}: {}", "action", self.action())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> TransferCotaNFTV1EntriesReader<'r> { + pub const FIELD_COUNT: usize = 7; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn claim_keys(&self) -> ClaimCotaNFTKeyVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ClaimCotaNFTKeyVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn claim_values(&self) -> ClaimCotaNFTValueVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + ClaimCotaNFTValueVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_keys(&self) -> WithdrawalCotaNFTKeyV1VecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + WithdrawalCotaNFTKeyV1VecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_values(&self) -> WithdrawalCotaNFTValueV1VecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + WithdrawalCotaNFTValueV1VecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn proof(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_proof(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn action(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BytesReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for TransferCotaNFTV1EntriesReader<'r> { + type Entity = TransferCotaNFTV1Entries; + + const NAME: &'static str = "TransferCotaNFTV1EntriesReader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + TransferCotaNFTV1EntriesReader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + ClaimCotaNFTKeyVecReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + ClaimCotaNFTValueVecReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + WithdrawalCotaNFTKeyV1VecReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + WithdrawalCotaNFTValueV1VecReader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + BytesReader::verify(&slice[offsets[4]..offsets[5]], compatible)?; + BytesReader::verify(&slice[offsets[5]..offsets[6]], compatible)?; + BytesReader::verify(&slice[offsets[6]..offsets[7]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct TransferCotaNFTV1EntriesBuilder { + pub(crate) claim_keys: ClaimCotaNFTKeyVec, + pub(crate) claim_values: ClaimCotaNFTValueVec, + pub(crate) withdrawal_keys: WithdrawalCotaNFTKeyV1Vec, + pub(crate) withdrawal_values: WithdrawalCotaNFTValueV1Vec, + pub(crate) proof: Bytes, + pub(crate) withdrawal_proof: Bytes, + pub(crate) action: Bytes, +} +impl TransferCotaNFTV1EntriesBuilder { + pub const FIELD_COUNT: usize = 7; + + pub fn claim_keys(mut self, v: ClaimCotaNFTKeyVec) -> Self { + self.claim_keys = v; + self + } + + pub fn claim_values(mut self, v: ClaimCotaNFTValueVec) -> Self { + self.claim_values = v; + self + } + + pub fn withdrawal_keys(mut self, v: WithdrawalCotaNFTKeyV1Vec) -> Self { + self.withdrawal_keys = v; + self + } + + pub fn withdrawal_values(mut self, v: WithdrawalCotaNFTValueV1Vec) -> Self { + self.withdrawal_values = v; + self + } + + pub fn proof(mut self, v: Bytes) -> Self { + self.proof = v; + self + } + + pub fn withdrawal_proof(mut self, v: Bytes) -> Self { + self.withdrawal_proof = v; + self + } + + pub fn action(mut self, v: Bytes) -> Self { + self.action = v; + self + } +} +impl molecule::prelude::Builder for TransferCotaNFTV1EntriesBuilder { + type Entity = TransferCotaNFTV1Entries; + + const NAME: &'static str = "TransferCotaNFTV1EntriesBuilder"; + + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.claim_keys.as_slice().len() + + self.claim_values.as_slice().len() + + self.withdrawal_keys.as_slice().len() + + self.withdrawal_values.as_slice().len() + + self.proof.as_slice().len() + + self.withdrawal_proof.as_slice().len() + + self.action.as_slice().len() + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.claim_keys.as_slice().len(); + offsets.push(total_size); + total_size += self.claim_values.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_keys.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_values.as_slice().len(); + offsets.push(total_size); + total_size += self.proof.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_proof.as_slice().len(); + offsets.push(total_size); + total_size += self.action.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.claim_keys.as_slice())?; + writer.write_all(self.claim_values.as_slice())?; + writer.write_all(self.withdrawal_keys.as_slice())?; + writer.write_all(self.withdrawal_values.as_slice())?; + writer.write_all(self.proof.as_slice())?; + writer.write_all(self.withdrawal_proof.as_slice())?; + writer.write_all(self.action.as_slice())?; + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + TransferCotaNFTV1Entries::new_unchecked(inner.into()) + } +} diff --git a/src/transfer_update.mol b/src/transfer_update.mol index 54c9825..403f270 100644 --- a/src/transfer_update.mol +++ b/src/transfer_update.mol @@ -18,4 +18,15 @@ table TransferUpdateCotaNFTEntries { proof: Bytes, withdrawal_proof: Bytes, action: Bytes, -} \ No newline at end of file +} + +// V1 +table TransferUpdateCotaNFTV1Entries { + claim_keys: ClaimCotaNFTKeyVec, + claim_infos: ClaimCotaNFTInfoVec, + withdrawal_keys: WithdrawalCotaNFTKeyV1Vec, + withdrawal_values: WithdrawalCotaNFTValueV1Vec, + proof: Bytes, + withdrawal_proof: Bytes, + action: Bytes, +} diff --git a/src/transfer_update.rs b/src/transfer_update.rs index 0066552..e70dce6 100644 --- a/src/transfer_update.rs +++ b/src/transfer_update.rs @@ -9,7 +9,6 @@ use super::molecule::{self, prelude::*}; extern crate alloc; pub use alloc::vec::*; // these lines above are manually added -// replace "::molecule" to "molecule" in below code use super::common::*; use molecule::prelude::*; @@ -891,3 +890,442 @@ impl molecule::prelude::Builder for TransferUpdateCotaNFTEntriesBuilder { TransferUpdateCotaNFTEntries::new_unchecked(inner.into()) } } +#[derive(Clone)] +pub struct TransferUpdateCotaNFTV1Entries(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for TransferUpdateCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for TransferUpdateCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for TransferUpdateCotaNFTV1Entries { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "claim_keys", self.claim_keys())?; + write!(f, ", {}: {}", "claim_infos", self.claim_infos())?; + write!(f, ", {}: {}", "withdrawal_keys", self.withdrawal_keys())?; + write!(f, ", {}: {}", "withdrawal_values", self.withdrawal_values())?; + write!(f, ", {}: {}", "proof", self.proof())?; + write!(f, ", {}: {}", "withdrawal_proof", self.withdrawal_proof())?; + write!(f, ", {}: {}", "action", self.action())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for TransferUpdateCotaNFTV1Entries { + fn default() -> Self { + let v: Vec = vec![ + 60, 0, 0, 0, 32, 0, 0, 0, 36, 0, 0, 0, 40, 0, 0, 0, 44, 0, 0, 0, 48, 0, 0, 0, 52, 0, 0, + 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]; + TransferUpdateCotaNFTV1Entries::new_unchecked(v.into()) + } +} +impl TransferUpdateCotaNFTV1Entries { + pub const FIELD_COUNT: usize = 7; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn claim_keys(&self) -> ClaimCotaNFTKeyVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ClaimCotaNFTKeyVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn claim_infos(&self) -> ClaimCotaNFTInfoVec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + ClaimCotaNFTInfoVec::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_keys(&self) -> WithdrawalCotaNFTKeyV1Vec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + WithdrawalCotaNFTKeyV1Vec::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_values(&self) -> WithdrawalCotaNFTValueV1Vec { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + WithdrawalCotaNFTValueV1Vec::new_unchecked(self.0.slice(start..end)) + } + + pub fn proof(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } + + pub fn withdrawal_proof(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } + + pub fn action(&self) -> Bytes { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + Bytes::new_unchecked(self.0.slice(start..end)) + } else { + Bytes::new_unchecked(self.0.slice(start..)) + } + } + + pub fn as_reader<'r>(&'r self) -> TransferUpdateCotaNFTV1EntriesReader<'r> { + TransferUpdateCotaNFTV1EntriesReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for TransferUpdateCotaNFTV1Entries { + type Builder = TransferUpdateCotaNFTV1EntriesBuilder; + + const NAME: &'static str = "TransferUpdateCotaNFTV1Entries"; + + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + TransferUpdateCotaNFTV1Entries(data) + } + + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TransferUpdateCotaNFTV1EntriesReader::from_slice(slice).map(|reader| reader.to_entity()) + } + + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TransferUpdateCotaNFTV1EntriesReader::from_compatible_slice(slice) + .map(|reader| reader.to_entity()) + } + + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .claim_keys(self.claim_keys()) + .claim_infos(self.claim_infos()) + .withdrawal_keys(self.withdrawal_keys()) + .withdrawal_values(self.withdrawal_values()) + .proof(self.proof()) + .withdrawal_proof(self.withdrawal_proof()) + .action(self.action()) + } +} +#[derive(Clone, Copy)] +pub struct TransferUpdateCotaNFTV1EntriesReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for TransferUpdateCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for TransferUpdateCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for TransferUpdateCotaNFTV1EntriesReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "claim_keys", self.claim_keys())?; + write!(f, ", {}: {}", "claim_infos", self.claim_infos())?; + write!(f, ", {}: {}", "withdrawal_keys", self.withdrawal_keys())?; + write!(f, ", {}: {}", "withdrawal_values", self.withdrawal_values())?; + write!(f, ", {}: {}", "proof", self.proof())?; + write!(f, ", {}: {}", "withdrawal_proof", self.withdrawal_proof())?; + write!(f, ", {}: {}", "action", self.action())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> TransferUpdateCotaNFTV1EntriesReader<'r> { + pub const FIELD_COUNT: usize = 7; + + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + + pub fn claim_keys(&self) -> ClaimCotaNFTKeyVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + ClaimCotaNFTKeyVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn claim_infos(&self) -> ClaimCotaNFTInfoVecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + ClaimCotaNFTInfoVecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_keys(&self) -> WithdrawalCotaNFTKeyV1VecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + WithdrawalCotaNFTKeyV1VecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_values(&self) -> WithdrawalCotaNFTValueV1VecReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + WithdrawalCotaNFTValueV1VecReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn proof(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn withdrawal_proof(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + let end = molecule::unpack_number(&slice[28..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } + + pub fn action(&self) -> BytesReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[28..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[32..]) as usize; + BytesReader::new_unchecked(&self.as_slice()[start..end]) + } else { + BytesReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for TransferUpdateCotaNFTV1EntriesReader<'r> { + type Entity = TransferUpdateCotaNFTV1Entries; + + const NAME: &'static str = "TransferUpdateCotaNFTV1EntriesReader"; + + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + + fn new_unchecked(slice: &'r [u8]) -> Self { + TransferUpdateCotaNFTV1EntriesReader(slice) + } + + fn as_slice(&self) -> &'r [u8] { + self.0 + } + + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len == molecule::NUMBER_SIZE && Self::FIELD_COUNT == 0 { + return Ok(()); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + ClaimCotaNFTKeyVecReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + ClaimCotaNFTInfoVecReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + WithdrawalCotaNFTKeyV1VecReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + WithdrawalCotaNFTValueV1VecReader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + BytesReader::verify(&slice[offsets[4]..offsets[5]], compatible)?; + BytesReader::verify(&slice[offsets[5]..offsets[6]], compatible)?; + BytesReader::verify(&slice[offsets[6]..offsets[7]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct TransferUpdateCotaNFTV1EntriesBuilder { + pub(crate) claim_keys: ClaimCotaNFTKeyVec, + pub(crate) claim_infos: ClaimCotaNFTInfoVec, + pub(crate) withdrawal_keys: WithdrawalCotaNFTKeyV1Vec, + pub(crate) withdrawal_values: WithdrawalCotaNFTValueV1Vec, + pub(crate) proof: Bytes, + pub(crate) withdrawal_proof: Bytes, + pub(crate) action: Bytes, +} +impl TransferUpdateCotaNFTV1EntriesBuilder { + pub const FIELD_COUNT: usize = 7; + + pub fn claim_keys(mut self, v: ClaimCotaNFTKeyVec) -> Self { + self.claim_keys = v; + self + } + + pub fn claim_infos(mut self, v: ClaimCotaNFTInfoVec) -> Self { + self.claim_infos = v; + self + } + + pub fn withdrawal_keys(mut self, v: WithdrawalCotaNFTKeyV1Vec) -> Self { + self.withdrawal_keys = v; + self + } + + pub fn withdrawal_values(mut self, v: WithdrawalCotaNFTValueV1Vec) -> Self { + self.withdrawal_values = v; + self + } + + pub fn proof(mut self, v: Bytes) -> Self { + self.proof = v; + self + } + + pub fn withdrawal_proof(mut self, v: Bytes) -> Self { + self.withdrawal_proof = v; + self + } + + pub fn action(mut self, v: Bytes) -> Self { + self.action = v; + self + } +} +impl molecule::prelude::Builder for TransferUpdateCotaNFTV1EntriesBuilder { + type Entity = TransferUpdateCotaNFTV1Entries; + + const NAME: &'static str = "TransferUpdateCotaNFTV1EntriesBuilder"; + + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.claim_keys.as_slice().len() + + self.claim_infos.as_slice().len() + + self.withdrawal_keys.as_slice().len() + + self.withdrawal_values.as_slice().len() + + self.proof.as_slice().len() + + self.withdrawal_proof.as_slice().len() + + self.action.as_slice().len() + } + + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.claim_keys.as_slice().len(); + offsets.push(total_size); + total_size += self.claim_infos.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_keys.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_values.as_slice().len(); + offsets.push(total_size); + total_size += self.proof.as_slice().len(); + offsets.push(total_size); + total_size += self.withdrawal_proof.as_slice().len(); + offsets.push(total_size); + total_size += self.action.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.claim_keys.as_slice())?; + writer.write_all(self.claim_infos.as_slice())?; + writer.write_all(self.withdrawal_keys.as_slice())?; + writer.write_all(self.withdrawal_values.as_slice())?; + writer.write_all(self.proof.as_slice())?; + writer.write_all(self.withdrawal_proof.as_slice())?; + writer.write_all(self.action.as_slice())?; + Ok(()) + } + + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + TransferUpdateCotaNFTV1Entries::new_unchecked(inner.into()) + } +} diff --git a/src/update.mol b/src/update.mol index 85ad201..a19f7ec 100644 --- a/src/update.mol +++ b/src/update.mol @@ -6,4 +6,4 @@ table UpdateCotaNFTEntries { hold_new_values: HoldCotaNFTValueVec, proof: Bytes, action: Bytes, -} \ No newline at end of file +} diff --git a/src/update.rs b/src/update.rs index 4d62e15..5de9f00 100644 --- a/src/update.rs +++ b/src/update.rs @@ -9,7 +9,6 @@ use super::molecule::{self, prelude::*}; extern crate alloc; pub use alloc::vec::*; // these lines above are manually added -// replace "::molecule" to "molecule" in below code use super::common::*; use molecule::prelude::*;