diff --git a/Cargo.toml b/Cargo.toml index 749095a..031ac05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "joyid-smt" -version = "0.3.0" +version = "0.4.0" edition = "2018" diff --git a/src/extension.mol b/src/extension.mol index 36ecd29..606b8a1 100644 --- a/src/extension.mol +++ b/src/extension.mol @@ -1,6 +1,5 @@ import common; -vector LockScriptVec ; vector ExtensionVec ; table ExtensionLeaves { diff --git a/src/extension.rs b/src/extension.rs index d6192e2..869bb77 100644 --- a/src/extension.rs +++ b/src/extension.rs @@ -13,345 +13,6 @@ pub use alloc::vec::*; use super::common::*; use molecule::prelude::*; #[derive(Clone)] -pub struct LockScriptVec(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for LockScriptVec { - 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 LockScriptVec { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for LockScriptVec { - 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 LockScriptVec { - fn default() -> Self { - let v: Vec = vec![4, 0, 0, 0]; - LockScriptVec::new_unchecked(v.into()) - } -} -impl LockScriptVec { - 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) -> Bytes { - 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 { - Bytes::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; - Bytes::new_unchecked(self.0.slice(start..end)) - } - } - pub fn as_reader<'r>(&'r self) -> LockScriptVecReader<'r> { - LockScriptVecReader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for LockScriptVec { - type Builder = LockScriptVecBuilder; - const NAME: &'static str = "LockScriptVec"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - LockScriptVec(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 { - LockScriptVecReader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - LockScriptVecReader::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 LockScriptVecReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for LockScriptVecReader<'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 LockScriptVecReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for LockScriptVecReader<'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> LockScriptVecReader<'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) -> BytesReader<'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 { - BytesReader::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; - BytesReader::new_unchecked(&self.as_slice()[start..end]) - } - } -} -impl<'r> molecule::prelude::Reader<'r> for LockScriptVecReader<'r> { - type Entity = LockScriptVec; - const NAME: &'static str = "LockScriptVecReader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - LockScriptVecReader(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]; - BytesReader::verify(&slice[start..end], compatible)?; - } - Ok(()) - } -} -#[derive(Debug, Default)] -pub struct LockScriptVecBuilder(pub(crate) Vec); -impl LockScriptVecBuilder { - pub fn set(mut self, v: Vec) -> Self { - self.0 = v; - self - } - pub fn push(mut self, v: Bytes) -> 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: Bytes) -> Option { - self.0 - .get_mut(index) - .map(|item| ::core::mem::replace(item, v)) - } -} -impl molecule::prelude::Builder for LockScriptVecBuilder { - type Entity = LockScriptVec; - const NAME: &'static str = "LockScriptVecBuilder"; - 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)); - LockScriptVec::new_unchecked(inner.into()) - } -} -pub struct LockScriptVecIterator(LockScriptVec, usize, usize); -impl ::core::iter::Iterator for LockScriptVecIterator { - type Item = Bytes; - 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 LockScriptVecIterator { - fn len(&self) -> usize { - self.2 - self.1 - } -} -impl ::core::iter::IntoIterator for LockScriptVec { - type Item = Bytes; - type IntoIter = LockScriptVecIterator; - fn into_iter(self) -> Self::IntoIter { - let len = self.len(); - LockScriptVecIterator(self, 0, len) - } -} -impl<'r> LockScriptVecReader<'r> { - pub fn iter<'t>(&'t self) -> LockScriptVecReaderIterator<'t, 'r> { - LockScriptVecReaderIterator(&self, 0, self.len()) - } -} -pub struct LockScriptVecReaderIterator<'t, 'r>(&'t LockScriptVecReader<'r>, usize, usize); -impl<'t: 'r, 'r> ::core::iter::Iterator for LockScriptVecReaderIterator<'t, 'r> { - type Item = BytesReader<'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 LockScriptVecReaderIterator<'t, 'r> { - fn len(&self) -> usize { - self.2 - self.1 - } -} -#[derive(Clone)] pub struct ExtensionVec(molecule::bytes::Bytes); impl ::core::fmt::LowerHex for ExtensionVec { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {