From 1569874128c9ec8cbbf1d67a83b65981558cfaa1 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 19 Oct 2024 02:37:26 +0200 Subject: [PATCH] implement Display in terms of STON --- src/rgb21/types.rs | 106 +++++++++++++++++++++++++++++++++++++++------ src/stl/asset.rs | 3 +- src/stl/chain.rs | 8 ++++ src/stl/specs.rs | 81 +++++++++++++++++++++++++++++++++- 4 files changed, 182 insertions(+), 16 deletions(-) diff --git a/src/rgb21/types.rs b/src/rgb21/types.rs index d43090a..e032d39 100644 --- a/src/rgb21/types.rs +++ b/src/rgb21/types.rs @@ -23,7 +23,7 @@ use std::collections::BTreeMap; use std::fmt; -use std::fmt::{Debug, Formatter}; +use std::fmt::{Debug, Display, Formatter}; use std::str::FromStr; use amplify::ascii::AsciiString; @@ -71,6 +71,12 @@ pub struct EngravingData { impl StrictSerialize for EngravingData {} impl StrictDeserialize for EngravingData {} +impl Display for EngravingData { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "appliedTo {}, content {}", self.applied_to, self.content) + } +} + #[derive(Clone, Eq, PartialEq, Hash, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB21)] @@ -86,6 +92,12 @@ pub struct EmbeddedMedia { pub data: SmallBlob, } +impl Display for EmbeddedMedia { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "type {}, data 0x{:X}", self.ty, self.data) + } +} + #[derive(Clone, Eq, PartialEq, Hash, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB21, dumb = { AttachmentType::with(0, "dumb") })] @@ -185,6 +197,61 @@ pub struct TokenData { impl StrictSerialize for TokenData {} impl StrictDeserialize for TokenData {} +impl Display for TokenData { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "index {}", self.index)?; + + f.write_str(", ticker ")?; + if let Some(ticker) = &self.ticker { + write!(f, "{ticker}")?; + } else { + f.write_str("~")?; + } + + f.write_str(", name ")?; + if let Some(name) = &self.name { + write!(f, "{name}")?; + } else { + f.write_str("~")?; + } + + f.write_str(", details ")?; + if let Some(details) = &self.details { + write!(f, "{details}")?; + } else { + f.write_str("~")?; + } + + f.write_str(",\npreview ")?; + if let Some(preview) = &self.preview { + write!(f, "{preview}")?; + } else { + f.write_str("~")?; + } + + f.write_str(",\nmedia ")?; + if let Some(media) = &self.media { + write!(f, "{media}")?; + } else { + f.write_str("~")?; + } + + f.write_str(",\nattachments {")?; + for (id, attach) in &self.attachments { + writeln!(f, " {id} -> {attach}")?; + } + + f.write_str("},\nreserves ")?; + if let Some(reserves) = &self.reserves { + write!(f, "{reserves}")?; + } else { + f.write_str("~")?; + } + + Ok(()) + } +} + #[derive(Clone, PartialEq, Eq, Debug, Display, Error, From)] #[display(inner)] pub enum AllocationParseError { @@ -206,7 +273,7 @@ pub enum AllocationParseError { )] #[wrapper(Display, FromStr, Add, Sub, Mul, Div, Rem)] #[wrapper_mut(AddAssign, SubAssign, MulAssign, DivAssign, RemAssign)] -#[derive(StrictType, strict_encoding::StrictEncode, StrictDecode)] +#[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_CONTRACT)] #[cfg_attr( feature = "serde", @@ -220,7 +287,7 @@ pub struct TokenIndex(u32); )] #[wrapper(Display, FromStr, Add, Sub, Mul, Div, Rem)] #[wrapper_mut(AddAssign, SubAssign, MulAssign, DivAssign, RemAssign)] -#[derive(StrictType, strict_encoding::StrictEncode, StrictDecode)] +#[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_CONTRACT)] #[cfg_attr( feature = "serde", @@ -269,26 +336,37 @@ impl OwnedFraction { } } -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default, Display)] -#[display("{1}@{0}")] -#[derive(StrictType, strict_encoding::StrictEncode, StrictDecode)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)] +#[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_CONTRACT)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct NftAllocation(TokenIndex, OwnedFraction); +pub struct NftAllocation { + pub token: TokenIndex, + pub fraction: OwnedFraction, +} impl NftAllocation { pub fn with(index: impl Into, fraction: impl Into) -> NftAllocation { - NftAllocation(index.into(), fraction.into()) + NftAllocation { + token: index.into(), + fraction: fraction.into(), + } } - pub fn token_index(self) -> TokenIndex { self.0 } + pub fn token_index(self) -> TokenIndex { self.token } - pub fn fraction(self) -> OwnedFraction { self.1 } + pub fn fraction(self) -> OwnedFraction { self.fraction } } impl StrictSerialize for NftAllocation {} impl StrictDeserialize for NftAllocation {} +impl Display for NftAllocation { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "token {}, fraction {}", self.token, self.fraction) + } +} + impl FromStr for NftAllocation { type Err = AllocationParseError; @@ -298,14 +376,14 @@ impl FromStr for NftAllocation { } match s.split_once('@') { - Some((fraction, token_index)) => Ok(NftAllocation( - token_index + Some((fraction, token_index)) => Ok(NftAllocation { + token: token_index .parse() .map_err(|_| AllocationParseError::InvalidIndex(token_index.to_owned()))?, - fraction + fraction: fraction .parse() .map_err(|_| AllocationParseError::InvalidFraction(fraction.to_lowercase()))?, - )), + }), None => Err(AllocationParseError::WrongFormat), } } diff --git a/src/stl/asset.rs b/src/stl/asset.rs index 8f919fa..eb524ea 100644 --- a/src/stl/asset.rs +++ b/src/stl/asset.rs @@ -149,7 +149,8 @@ impl Sum for Amount { } } -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)] +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default, Display)] +#[display(lowercase)] #[repr(u8)] #[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_CONTRACT, tags = repr, into_u8, try_from_u8)] diff --git a/src/stl/chain.rs b/src/stl/chain.rs index 29aed06..5a5c215 100644 --- a/src/stl/chain.rs +++ b/src/stl/chain.rs @@ -19,6 +19,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::fmt::{Display, Formatter}; + use amplify::confinement::SmallBlob; use bp::Outpoint; use strict_encoding::{StrictDeserialize, StrictSerialize}; @@ -36,6 +38,12 @@ pub struct ProofOfReserves { impl StrictSerialize for ProofOfReserves {} impl StrictDeserialize for ProofOfReserves {} +impl Display for ProofOfReserves { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "utxo {}, proof 0x{:X}", self.utxo, self.proof) + } +} + impl ProofOfReserves { pub fn new(utxo: Outpoint, proof: SmallBlob) -> ProofOfReserves { ProofOfReserves { utxo, proof } diff --git a/src/stl/specs.rs b/src/stl/specs.rs index 9fe5fac..5c1ba4d 100644 --- a/src/stl/specs.rs +++ b/src/stl/specs.rs @@ -21,7 +21,7 @@ #![allow(unused_braces)] // caused by rustc unable to understand strict_dumb -use std::fmt::{self, Debug, Formatter}; +use std::fmt::{self, Debug, Display, Formatter}; use std::hash::{Hash, Hasher}; use std::str::FromStr; @@ -49,6 +49,16 @@ pub struct BurnMeta { impl StrictSerialize for BurnMeta {} impl StrictDeserialize for BurnMeta {} +impl Display for BurnMeta { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + writeln!(f, "burnProofs {{")?; + for proof in &self.burn_proofs { + writeln!(f, " {proof}")?; + } + writeln!(f, "}}") + } +} + #[derive(Clone, Eq, PartialEq, Hash, Debug, Default)] #[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_CONTRACT)] @@ -63,6 +73,16 @@ pub struct IssueMeta { impl StrictSerialize for IssueMeta {} impl StrictDeserialize for IssueMeta {} +impl Display for IssueMeta { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + writeln!(f, "reserves {{")?; + for proof in &self.reserves { + writeln!(f, " {proof}")?; + } + writeln!(f, "}}") + } +} + #[derive(Wrapper, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, From)] #[wrapper(Deref, Display, FromStr)] #[derive(StrictDumb, StrictType, StrictEncode, StrictDecode)] @@ -191,6 +211,22 @@ pub struct AssetSpec { impl StrictSerialize for AssetSpec {} impl StrictDeserialize for AssetSpec {} +impl Display for AssetSpec { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "ticker {}, name {}, details {}, precision {}", + self.ticker, + self.name, + self.details + .as_ref() + .map(Details::to_string) + .unwrap_or_else(|| s!("~")), + self.precision + ) + } +} + impl AssetSpec { pub fn new(ticker: &'static str, name: &'static str, precision: Precision) -> AssetSpec { AssetSpec { @@ -239,6 +275,28 @@ pub struct ContractSpec { impl StrictSerialize for ContractSpec {} impl StrictDeserialize for ContractSpec {} +impl Display for ContractSpec { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("article ")?; + if let Some(article) = &self.article { + write!(f, "{article}")?; + } else { + f.write_str("~")?; + } + + write!(f, ", name {}", self.name)?; + + f.write_str(", details ")?; + if let Some(details) = &self.details { + write!(f, "{details}")?; + } else { + f.write_str("~")?; + } + + write!(f, ", precision {}", self.precision) + } +} + impl ContractSpec { pub fn new(name: &'static str, precision: Precision) -> ContractSpec { ContractSpec { @@ -314,6 +372,12 @@ pub struct Attachment { impl StrictSerialize for Attachment {} impl StrictDeserialize for Attachment {} +impl Display for Attachment { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "type {}, digest 0x{}", self.ty, self.digest) + } +} + #[derive(Clone, Eq, PartialEq, Hash, Debug)] #[derive(StrictDumb, StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_CONTRACT)] @@ -328,3 +392,18 @@ pub struct ContractTerms { } impl StrictSerialize for ContractTerms {} impl StrictDeserialize for ContractTerms {} + +impl Display for ContractTerms { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "text {}", self.text)?; + + f.write_str(", media ")?; + if let Some(media) = &self.media { + write!(f, "{media}")?; + } else { + f.write_str("~")?; + } + + Ok(()) + } +}