diff --git a/src/interface/iface.rs b/src/interface/iface.rs index 8d70e5c3..fc31181a 100644 --- a/src/interface/iface.rs +++ b/src/interface/iface.rs @@ -37,8 +37,8 @@ use strict_encoding::{ }; use strict_types::{SemId, SymbolicSys, TypeLib}; -use crate::interface::{IfaceDisplay, IfaceImpl, VerNo}; -use crate::persistence::SchemaIfaces; +use crate::interface::{ContractIface, IfaceDisplay, IfaceImpl, VerNo}; +use crate::persistence::{ContractStateRead, SchemaIfaces}; use crate::LIB_NAME_RGB_STD; /// Interface identifier. @@ -336,24 +336,25 @@ pub struct TransitionIface { /// /// Interface standards like RGB20, RGB21 and RGB25 are actually interface /// classes. -/// -/// The instances implementing this trait are used as wrappers around -/// [`ContractIface`] object, allowing a simple API matching the interface class -/// requirements. -pub trait IfaceClass { +pub trait IfaceClass: Clone + Default { const IFACE_NAME: &'static str; const IFACE_IDS: &'static [IfaceId]; - /// An object which allows to configure specific interface features to - /// select one interface from the class. - type Features: Sized + Clone + Default; + type Wrapper: IfaceWrapper; + fn stl(&self) -> TypeLib; + fn iface(&self) -> Iface; + fn iface_id(&self) -> IfaceId; +} + +/// The instances implementing this trait are used as wrappers around +/// [`ContractIface`] object, allowing a simple API matching the interface class +/// requirements. +pub trait IfaceWrapper { /// Object which represent concise summary about a contract; type Info: Clone + Eq + Debug; - fn iface(features: Self::Features) -> Iface; - fn iface_id(features: Self::Features) -> IfaceId; - fn stl() -> TypeLib; + fn with(iface: ContractIface) -> Self; /// Constructs information object describing a specific class in terms of /// the interface class. diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 03a613ca..ea5ef2d9 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -41,7 +41,8 @@ pub use contractum::IfaceDisplay; pub use filter::{FilterExclude, FilterIncludeAll, OutpointFilter}; pub use iface::{ ArgMap, AssignIface, ExtensionIface, GenesisIface, GlobalIface, Iface, IfaceClass, IfaceId, - IfaceInconsistency, IfaceRef, Modifier, OpName, OwnedIface, Req, TransitionIface, ValencyIface, + IfaceInconsistency, IfaceRef, IfaceWrapper, Modifier, OpName, OwnedIface, Req, TransitionIface, + ValencyIface, }; pub use iimpl::{IfaceImpl, ImplId, NamedField, NamedType, NamedVariant, SchemaTypeIndex}; pub use inheritance::{CheckInheritance, ExtensionError, InheritanceFailure}; diff --git a/src/persistence/stock.rs b/src/persistence/stock.rs index 11b282ad..6bdb663b 100644 --- a/src/persistence/stock.rs +++ b/src/persistence/stock.rs @@ -56,7 +56,7 @@ use crate::containers::{ use crate::info::{ContractInfo, IfaceInfo, SchemaInfo}; use crate::interface::{ BuilderError, ContractBuilder, ContractIface, Iface, IfaceClass, IfaceId, IfaceRef, - TransitionBuilder, + IfaceWrapper, TransitionBuilder, }; use crate::{MergeRevealError, RevealError}; @@ -502,12 +502,16 @@ impl Stock { #[allow(clippy::multiple_bound_locations)] pub fn contracts_by<'a, C: IfaceClass + 'a>( &'a self, - ) -> Result + 'a, StockError> - where C: From>> { + ) -> Result< + impl Iterator< + Item = > as IfaceWrapper>>::Info, + > + 'a, + StockError, + > { Ok(self.stash.geneses_by::()?.filter_map(|genesis| { self.contract_iface_class::(genesis.contract_id()) .as_ref() - .map(C::info) + .map(> as IfaceWrapper>>::info) .ok() })) } @@ -547,27 +551,23 @@ impl Stock { } #[allow(clippy::multiple_bound_locations)] - pub fn contract_iface_class<'a, C: IfaceClass>( - &'a self, + pub fn contract_iface_class( + &self, contract_id: ContractId, - ) -> Result> - where - C: From>>, - { + ) -> Result>, StockError> { let (schema_ifaces, state, info) = self.contract_raw(contract_id)?; let iimpl = self.stash.impl_for::(schema_ifaces)?; let iface = self.stash.iface(iimpl.iface_id)?; let (types, _) = self.stash.extract(&schema_ifaces.schema, [iface])?; - Ok(ContractIface { + Ok(C::Wrapper::with(ContractIface { state, schema: schema_ifaces.schema.clone(), iface: iimpl.clone(), types, info, - } - .into()) + })) } /// Returns the best matching abstract interface to a contract.