diff --git a/Makefile b/Makefile index 74915ea..edd1f00 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ all: mol: moleculec --language rust --schema-file schemas/basic.mol > ckb-typed-message/src/schemas/basic.rs moleculec --language rust --schema-file schemas/top_level.mol > ckb-typed-message/src/schemas/top_level.rs + moleculec --language rust --schema-file schemas/spore.mol > ckb-typed-message/src/schemas/spore.rs cargo fmt install: diff --git a/ckb-typed-message/src/schemas/basic.rs b/ckb-typed-message/src/schemas/basic.rs index b796a9c..f95e485 100644 --- a/ckb-typed-message/src/schemas/basic.rs +++ b/ckb-typed-message/src/schemas/basic.rs @@ -513,6 +513,170 @@ impl<'r> AddressUnionReader<'r> { } } #[derive(Clone)] +pub struct AddressOpt(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for AddressOpt { + 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 AddressOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for AddressOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl ::core::default::Default for AddressOpt { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + AddressOpt::new_unchecked(v) + } +} +impl AddressOpt { + const DEFAULT_VALUE: [u8; 0] = []; + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option
{ + if self.is_none() { + None + } else { + Some(Address::new_unchecked(self.0.clone())) + } + } + pub fn as_reader<'r>(&'r self) -> AddressOptReader<'r> { + AddressOptReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for AddressOpt { + type Builder = AddressOptBuilder; + const NAME: &'static str = "AddressOpt"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + AddressOpt(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 { + AddressOptReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + AddressOptReader::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().set(self.to_opt()) + } +} +#[derive(Clone, Copy)] +pub struct AddressOptReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for AddressOptReader<'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 AddressOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for AddressOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl<'r> AddressOptReader<'r> { + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option> { + if self.is_none() { + None + } else { + Some(AddressReader::new_unchecked(self.as_slice())) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for AddressOptReader<'r> { + type Entity = AddressOpt; + const NAME: &'static str = "AddressOptReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + AddressOptReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + if !slice.is_empty() { + AddressReader::verify(&slice[..], compatible)?; + } + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct AddressOptBuilder(pub(crate) Option
); +impl AddressOptBuilder { + pub fn set(mut self, v: Option
) -> Self { + self.0 = v; + self + } +} +impl molecule::prelude::Builder for AddressOptBuilder { + type Entity = AddressOpt; + const NAME: &'static str = "AddressOptBuilder"; + fn expected_length(&self) -> usize { + self.0 + .as_ref() + .map(|ref inner| inner.as_slice().len()) + .unwrap_or(0) + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + self.0 + .as_ref() + .map(|ref inner| writer.write_all(inner.as_slice())) + .unwrap_or(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)); + AddressOpt::new_unchecked(inner.into()) + } +} +#[derive(Clone)] pub struct Action(molecule::bytes::Bytes); impl ::core::fmt::LowerHex for Action { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { diff --git a/ckb-typed-message/src/schemas/mod.rs b/ckb-typed-message/src/schemas/mod.rs index ecd0844..5c8677e 100644 --- a/ckb-typed-message/src/schemas/mod.rs +++ b/ckb-typed-message/src/schemas/mod.rs @@ -1,3 +1,4 @@ pub mod basic; pub mod blockchain; +pub mod spore; pub mod top_level; diff --git a/ckb-typed-message/src/schemas/spore.rs b/ckb-typed-message/src/schemas/spore.rs new file mode 100644 index 0000000..f0e554d --- /dev/null +++ b/ckb-typed-message/src/schemas/spore.rs @@ -0,0 +1,1152 @@ +// Generated by Molecule 0.7.5 + +use super::basic::*; +use super::blockchain::*; +use molecule::prelude::*; +#[derive(Clone)] +pub struct Mint(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Mint { + 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 Mint { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Mint { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "id", self.id())?; + write!(f, ", {}: {}", "to", self.to())?; + write!(f, ", {}: {}", "content_hash", self.content_hash())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for Mint { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + Mint::new_unchecked(v) + } +} +impl Mint { + const DEFAULT_VALUE: [u8; 137] = [ + 137, 0, 0, 0, 16, 0, 0, 0, 48, 0, 0, 0, 105, 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, 53, 0, 0, 0, 16, 0, + 0, 0, 48, 0, 0, 0, 49, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + pub const FIELD_COUNT: usize = 3; + 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 id(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn to(&self) -> Address { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Address::new_unchecked(self.0.slice(start..end)) + } + pub fn content_hash(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } else { + Byte32::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> MintReader<'r> { + MintReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Mint { + type Builder = MintBuilder; + const NAME: &'static str = "Mint"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Mint(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 { + MintReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + MintReader::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() + .id(self.id()) + .to(self.to()) + .content_hash(self.content_hash()) + } +} +#[derive(Clone, Copy)] +pub struct MintReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for MintReader<'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 MintReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for MintReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "id", self.id())?; + write!(f, ", {}: {}", "to", self.to())?; + write!(f, ", {}: {}", "content_hash", self.content_hash())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> MintReader<'r> { + pub const FIELD_COUNT: usize = 3; + 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 id(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn to(&self) -> AddressReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + AddressReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn content_hash(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } else { + Byte32Reader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for MintReader<'r> { + type Entity = Mint; + const NAME: &'static str = "MintReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + MintReader(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 * 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); + } + Byte32Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + AddressReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Byte32Reader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct MintBuilder { + pub(crate) id: Byte32, + pub(crate) to: Address, + pub(crate) content_hash: Byte32, +} +impl MintBuilder { + pub const FIELD_COUNT: usize = 3; + pub fn id(mut self, v: Byte32) -> Self { + self.id = v; + self + } + pub fn to(mut self, v: Address) -> Self { + self.to = v; + self + } + pub fn content_hash(mut self, v: Byte32) -> Self { + self.content_hash = v; + self + } +} +impl molecule::prelude::Builder for MintBuilder { + type Entity = Mint; + const NAME: &'static str = "MintBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.id.as_slice().len() + + self.to.as_slice().len() + + self.content_hash.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.id.as_slice().len(); + offsets.push(total_size); + total_size += self.to.as_slice().len(); + offsets.push(total_size); + total_size += self.content_hash.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.id.as_slice())?; + writer.write_all(self.to.as_slice())?; + writer.write_all(self.content_hash.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)); + Mint::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Transfer(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Transfer { + 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 Transfer { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Transfer { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "nft_id", self.nft_id())?; + write!(f, ", {}: {}", "from", self.from())?; + write!(f, ", {}: {}", "to", self.to())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for Transfer { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + Transfer::new_unchecked(v) + } +} +impl Transfer { + const DEFAULT_VALUE: [u8; 48] = [ + 48, 0, 0, 0, 16, 0, 0, 0, 48, 0, 0, 0, 48, 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, + ]; + pub const FIELD_COUNT: usize = 3; + 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_id(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn from(&self) -> AddressOpt { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + AddressOpt::new_unchecked(self.0.slice(start..end)) + } + pub fn to(&self) -> AddressOpt { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + AddressOpt::new_unchecked(self.0.slice(start..end)) + } else { + AddressOpt::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> TransferReader<'r> { + TransferReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Transfer { + type Builder = TransferBuilder; + const NAME: &'static str = "Transfer"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Transfer(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 { + TransferReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TransferReader::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()) + .from(self.from()) + .to(self.to()) + } +} +#[derive(Clone, Copy)] +pub struct TransferReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for TransferReader<'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 TransferReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for TransferReader<'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, ", {}: {}", "from", self.from())?; + write!(f, ", {}: {}", "to", self.to())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> TransferReader<'r> { + pub const FIELD_COUNT: usize = 3; + 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_id(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn from(&self) -> AddressOptReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + AddressOptReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn to(&self) -> AddressOptReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + AddressOptReader::new_unchecked(&self.as_slice()[start..end]) + } else { + AddressOptReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for TransferReader<'r> { + type Entity = Transfer; + const NAME: &'static str = "TransferReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + TransferReader(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 * 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); + } + Byte32Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + AddressOptReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + AddressOptReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct TransferBuilder { + pub(crate) nft_id: Byte32, + pub(crate) from: AddressOpt, + pub(crate) to: AddressOpt, +} +impl TransferBuilder { + pub const FIELD_COUNT: usize = 3; + pub fn nft_id(mut self, v: Byte32) -> Self { + self.nft_id = v; + self + } + pub fn from(mut self, v: AddressOpt) -> Self { + self.from = v; + self + } + pub fn to(mut self, v: AddressOpt) -> Self { + self.to = v; + self + } +} +impl molecule::prelude::Builder for TransferBuilder { + type Entity = Transfer; + const NAME: &'static str = "TransferBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.nft_id.as_slice().len() + + self.from.as_slice().len() + + self.to.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_id.as_slice().len(); + offsets.push(total_size); + total_size += self.from.as_slice().len(); + offsets.push(total_size); + total_size += self.to.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_id.as_slice())?; + writer.write_all(self.from.as_slice())?; + writer.write_all(self.to.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)); + Transfer::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct Melt(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Melt { + 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 Melt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Melt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "id", self.id())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for Melt { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + Melt::new_unchecked(v) + } +} +impl Melt { + const DEFAULT_VALUE: [u8; 40] = [ + 40, 0, 0, 0, 8, 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, + ]; + pub const FIELD_COUNT: usize = 1; + 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 id(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } else { + Byte32::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> MeltReader<'r> { + MeltReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Melt { + type Builder = MeltBuilder; + const NAME: &'static str = "Melt"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Melt(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 { + MeltReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + MeltReader::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().id(self.id()) + } +} +#[derive(Clone, Copy)] +pub struct MeltReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for MeltReader<'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 MeltReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for MeltReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "id", self.id())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> MeltReader<'r> { + pub const FIELD_COUNT: usize = 1; + 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 id(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[8..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } else { + Byte32Reader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for MeltReader<'r> { + type Entity = Melt; + const NAME: &'static str = "MeltReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + MeltReader(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 * 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); + } + Byte32Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct MeltBuilder { + pub(crate) id: Byte32, +} +impl MeltBuilder { + pub const FIELD_COUNT: usize = 1; + pub fn id(mut self, v: Byte32) -> Self { + self.id = v; + self + } +} +impl molecule::prelude::Builder for MeltBuilder { + type Entity = Melt; + const NAME: &'static str = "MeltBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + self.id.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.id.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.id.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)); + Melt::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct SporeAction(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for SporeAction { + 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 SporeAction { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for SporeAction { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") + } +} +impl ::core::default::Default for SporeAction { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + SporeAction::new_unchecked(v) + } +} +impl SporeAction { + const DEFAULT_VALUE: [u8; 141] = [ + 0, 0, 0, 0, 137, 0, 0, 0, 16, 0, 0, 0, 48, 0, 0, 0, 105, 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, 53, 0, + 0, 0, 16, 0, 0, 0, 48, 0, 0, 0, 49, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + pub const ITEMS_COUNT: usize = 3; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) + } + pub fn to_enum(&self) -> SporeActionUnion { + let inner = self.0.slice(molecule::NUMBER_SIZE..); + match self.item_id() { + 0 => Mint::new_unchecked(inner).into(), + 1 => Transfer::new_unchecked(inner).into(), + 2 => Melt::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } + } + pub fn as_reader<'r>(&'r self) -> SporeActionReader<'r> { + SporeActionReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for SporeAction { + type Builder = SporeActionBuilder; + const NAME: &'static str = "SporeAction"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + SporeAction(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 { + SporeActionReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + SporeActionReader::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().set(self.to_enum()) + } +} +#[derive(Clone, Copy)] +pub struct SporeActionReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for SporeActionReader<'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 SporeActionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for SporeActionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") + } +} +impl<'r> SporeActionReader<'r> { + pub const ITEMS_COUNT: usize = 3; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) + } + pub fn to_enum(&self) -> SporeActionUnionReader<'r> { + let inner = &self.as_slice()[molecule::NUMBER_SIZE..]; + match self.item_id() { + 0 => MintReader::new_unchecked(inner).into(), + 1 => TransferReader::new_unchecked(inner).into(), + 2 => MeltReader::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } + } +} +impl<'r> molecule::prelude::Reader<'r> for SporeActionReader<'r> { + type Entity = SporeAction; + const NAME: &'static str = "SporeActionReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + SporeActionReader(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_id = molecule::unpack_number(slice); + let inner_slice = &slice[molecule::NUMBER_SIZE..]; + match item_id { + 0 => MintReader::verify(inner_slice, compatible), + 1 => TransferReader::verify(inner_slice, compatible), + 2 => MeltReader::verify(inner_slice, compatible), + _ => ve!(Self, UnknownItem, Self::ITEMS_COUNT, item_id), + }?; + Ok(()) + } +} +#[derive(Debug, Default)] +pub struct SporeActionBuilder(pub(crate) SporeActionUnion); +impl SporeActionBuilder { + pub const ITEMS_COUNT: usize = 3; + pub fn set(mut self, v: I) -> Self + where + I: ::core::convert::Into, + { + self.0 = v.into(); + self + } +} +impl molecule::prelude::Builder for SporeActionBuilder { + type Entity = SporeAction; + const NAME: &'static str = "SporeActionBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE + self.0.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(&molecule::pack_number(self.0.item_id()))?; + writer.write_all(self.0.as_slice()) + } + 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)); + SporeAction::new_unchecked(inner.into()) + } +} +#[derive(Debug, Clone)] +pub enum SporeActionUnion { + Mint(Mint), + Transfer(Transfer), + Melt(Melt), +} +#[derive(Debug, Clone, Copy)] +pub enum SporeActionUnionReader<'r> { + Mint(MintReader<'r>), + Transfer(TransferReader<'r>), + Melt(MeltReader<'r>), +} +impl ::core::default::Default for SporeActionUnion { + fn default() -> Self { + SporeActionUnion::Mint(::core::default::Default::default()) + } +} +impl ::core::fmt::Display for SporeActionUnion { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + SporeActionUnion::Mint(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Mint::NAME, item) + } + SporeActionUnion::Transfer(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Transfer::NAME, item) + } + SporeActionUnion::Melt(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Melt::NAME, item) + } + } + } +} +impl<'r> ::core::fmt::Display for SporeActionUnionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + SporeActionUnionReader::Mint(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Mint::NAME, item) + } + SporeActionUnionReader::Transfer(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Transfer::NAME, item) + } + SporeActionUnionReader::Melt(ref item) => { + write!(f, "{}::{}({})", Self::NAME, Melt::NAME, item) + } + } + } +} +impl SporeActionUnion { + pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + SporeActionUnion::Mint(ref item) => write!(f, "{}", item), + SporeActionUnion::Transfer(ref item) => write!(f, "{}", item), + SporeActionUnion::Melt(ref item) => write!(f, "{}", item), + } + } +} +impl<'r> SporeActionUnionReader<'r> { + pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + SporeActionUnionReader::Mint(ref item) => write!(f, "{}", item), + SporeActionUnionReader::Transfer(ref item) => write!(f, "{}", item), + SporeActionUnionReader::Melt(ref item) => write!(f, "{}", item), + } + } +} +impl ::core::convert::From for SporeActionUnion { + fn from(item: Mint) -> Self { + SporeActionUnion::Mint(item) + } +} +impl ::core::convert::From for SporeActionUnion { + fn from(item: Transfer) -> Self { + SporeActionUnion::Transfer(item) + } +} +impl ::core::convert::From for SporeActionUnion { + fn from(item: Melt) -> Self { + SporeActionUnion::Melt(item) + } +} +impl<'r> ::core::convert::From> for SporeActionUnionReader<'r> { + fn from(item: MintReader<'r>) -> Self { + SporeActionUnionReader::Mint(item) + } +} +impl<'r> ::core::convert::From> for SporeActionUnionReader<'r> { + fn from(item: TransferReader<'r>) -> Self { + SporeActionUnionReader::Transfer(item) + } +} +impl<'r> ::core::convert::From> for SporeActionUnionReader<'r> { + fn from(item: MeltReader<'r>) -> Self { + SporeActionUnionReader::Melt(item) + } +} +impl SporeActionUnion { + pub const NAME: &'static str = "SporeActionUnion"; + pub fn as_bytes(&self) -> molecule::bytes::Bytes { + match self { + SporeActionUnion::Mint(item) => item.as_bytes(), + SporeActionUnion::Transfer(item) => item.as_bytes(), + SporeActionUnion::Melt(item) => item.as_bytes(), + } + } + pub fn as_slice(&self) -> &[u8] { + match self { + SporeActionUnion::Mint(item) => item.as_slice(), + SporeActionUnion::Transfer(item) => item.as_slice(), + SporeActionUnion::Melt(item) => item.as_slice(), + } + } + pub fn item_id(&self) -> molecule::Number { + match self { + SporeActionUnion::Mint(_) => 0, + SporeActionUnion::Transfer(_) => 1, + SporeActionUnion::Melt(_) => 2, + } + } + pub fn item_name(&self) -> &str { + match self { + SporeActionUnion::Mint(_) => "Mint", + SporeActionUnion::Transfer(_) => "Transfer", + SporeActionUnion::Melt(_) => "Melt", + } + } + pub fn as_reader<'r>(&'r self) -> SporeActionUnionReader<'r> { + match self { + SporeActionUnion::Mint(item) => item.as_reader().into(), + SporeActionUnion::Transfer(item) => item.as_reader().into(), + SporeActionUnion::Melt(item) => item.as_reader().into(), + } + } +} +impl<'r> SporeActionUnionReader<'r> { + pub const NAME: &'r str = "SporeActionUnionReader"; + pub fn as_slice(&self) -> &'r [u8] { + match self { + SporeActionUnionReader::Mint(item) => item.as_slice(), + SporeActionUnionReader::Transfer(item) => item.as_slice(), + SporeActionUnionReader::Melt(item) => item.as_slice(), + } + } + pub fn item_id(&self) -> molecule::Number { + match self { + SporeActionUnionReader::Mint(_) => 0, + SporeActionUnionReader::Transfer(_) => 1, + SporeActionUnionReader::Melt(_) => 2, + } + } + pub fn item_name(&self) -> &str { + match self { + SporeActionUnionReader::Mint(_) => "Mint", + SporeActionUnionReader::Transfer(_) => "Transfer", + SporeActionUnionReader::Melt(_) => "Melt", + } + } +} diff --git a/schemas/basic.mol b/schemas/basic.mol index d1dab9d..fe2e307 100644 --- a/schemas/basic.mol +++ b/schemas/basic.mol @@ -6,6 +6,8 @@ union Address { Script, } +option AddressOpt (Address); + table Action { info_hash: Byte32, data: Bytes, diff --git a/schemas/spore.mol b/schemas/spore.mol new file mode 100644 index 0000000..597c0e0 --- /dev/null +++ b/schemas/spore.mol @@ -0,0 +1,24 @@ +import blockchain; +import basic; + +table Mint { + id: Byte32, + to: Address, + content_hash: Byte32, +} + +table Transfer { + nft_id: Byte32, + from: AddressOpt, + to: AddressOpt, +} + +table Melt { + id: Byte32, +} + +union SporeAction { + Mint, + Transfer, + Melt, +}