diff --git a/Cargo.toml b/Cargo.toml index 6ca12034..2cd4c1aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,8 @@ std = [ derive = [ "scale-info-derive" ] +# enables decoding and deserialization of portable scale-info type metadata +decode = [] [workspace] members = [ diff --git a/src/form.rs b/src/form.rs index 3080b4c1..989d86a9 100644 --- a/src/form.rs +++ b/src/form.rs @@ -32,8 +32,6 @@ use crate::prelude::{ any::TypeId, fmt::Debug, - marker::PhantomData, - string::String, }; use crate::{ @@ -53,18 +51,9 @@ pub trait Form { /// The type representing the type. type Type: PartialEq + Eq + PartialOrd + Ord + Clone + Debug; /// The string type. - type String: FormString; + type String: AsRef + PartialEq + Eq + PartialOrd + Ord + Clone + Debug; } -/// Trait for types which can be used to represent strings in type definitions. -pub trait FormString: - AsRef + PartialEq + Eq + PartialOrd + Ord + Clone + Debug -{ -} - -impl FormString for &'static str {} -impl FormString for String {} - /// A meta meta-type. /// /// Allows to be converted into other forms such as portable form @@ -85,16 +74,21 @@ impl Form for MetaForm { /// This resolves some lifetime issues with self-referential structs (such as /// the registry itself) but can no longer be used to resolve to the original /// underlying data. -/// -/// `type String` is owned in order to enable decoding #[cfg_attr(feature = "serde", derive(Serialize))] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] -pub struct PortableForm(PhantomData); +pub enum PortableForm {} -impl Form for PortableForm -where - S: FormString, -{ - type Type = UntrackedSymbol; - type String = S; +cfg_if::cfg_if! { + if #[cfg(any(feature = "std", feature = "decode"))] { + impl Form for PortableForm { + type Type = UntrackedSymbol; + // Owned string required for decoding/deserialization + type String = crate::prelude::string::String; + } + } else { + impl Form for PortableForm { + type Type = UntrackedSymbol; + type String = &'static str; + } + } } diff --git a/src/registry.rs b/src/registry.rs index 79d69c61..6e29472c 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -34,7 +34,6 @@ use crate::prelude::{ use crate::{ form::{ Form, - FormString, PortableForm, }, interner::{ @@ -44,13 +43,9 @@ use crate::{ meta_type::MetaType, Type, }; -use scale::{ - Decode, - Encode, -}; +use scale::Encode; #[cfg(feature = "serde")] use serde::{ - de::DeserializeOwned, Deserialize, Serialize, }; @@ -68,7 +63,7 @@ impl IntoPortable for &'static str { type Output = ::String; fn into_portable(self, _registry: &mut Registry) -> Self::Output { - self + self.into() } } @@ -171,16 +166,10 @@ impl Registry { /// A read-only registry containing types in their portable form for serialization. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)] -#[cfg_attr( - feature = "serde", - serde(bound(serialize = "S: Serialize", deserialize = "S: DeserializeOwned")) -)] -pub struct PortableRegistry -where - S: FormString, -{ - types: Vec>>, +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(Clone, Debug, PartialEq, Eq, Encode)] +pub struct PortableRegistry { + types: Vec>, } impl From for PortableRegistry { @@ -191,19 +180,14 @@ impl From for PortableRegistry { } } -impl PortableRegistry -where - S: FormString, -{ +impl PortableRegistry { /// Returns the type definition for the given identifier, `None` if no type found for that ID. - pub fn resolve(&self, id: NonZeroU32) -> Option<&Type>> { + pub fn resolve(&self, id: NonZeroU32) -> Option<&Type> { self.types.get((id.get() - 1) as usize) } /// Returns an iterator for all types paired with their associated NonZeroU32 identifier. - pub fn enumerate( - &self, - ) -> impl Iterator>)> { + pub fn enumerate(&self) -> impl Iterator)> { self.types.iter().enumerate().map(|(i, ty)| { let id = NonZeroU32::new(i as u32 + 1).expect("i + 1 > 0; qed"); (id, ty) diff --git a/src/ty/composite.rs b/src/ty/composite.rs index 40f9e8d7..769c58b8 100644 --- a/src/ty/composite.rs +++ b/src/ty/composite.rs @@ -25,10 +25,7 @@ use crate::{ Registry, }; use derive_more::From; -use scale::{ - Decode, - Encode, -}; +use scale::Encode; #[cfg(feature = "serde")] use serde::{ de::DeserializeOwned, @@ -71,7 +68,8 @@ use serde::{ )) )] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, From, Encode, Decode)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, From, Encode)] pub struct TypeDefComposite { /// The fields of the composite type. #[cfg_attr( diff --git a/src/ty/fields.rs b/src/ty/fields.rs index 2b709289..1ef06ce9 100644 --- a/src/ty/fields.rs +++ b/src/ty/fields.rs @@ -24,7 +24,6 @@ use crate::{ TypeInfo, }; use scale::{ - Decode, Encode, HasCompact, }; @@ -66,7 +65,8 @@ use serde::{ /// may change. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Encode, Decode)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Encode)] pub struct Field { /// The name of the field. None for unnamed fields. #[cfg_attr( diff --git a/src/ty/mod.rs b/src/ty/mod.rs index 91429073..e3dd5cf4 100644 --- a/src/ty/mod.rs +++ b/src/ty/mod.rs @@ -30,10 +30,7 @@ use crate::{ TypeInfo, }; use derive_more::From; -use scale::{ - Decode, - Encode, -}; +use scale::Encode; #[cfg(feature = "serde")] use serde::{ de::DeserializeOwned, @@ -63,7 +60,8 @@ pub use self::{ )) )] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode, Decode)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode)] pub struct Type { /// The unique path to the type. Can be empty for built-in types #[cfg_attr( @@ -162,7 +160,8 @@ where )) )] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode, Decode)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, From, Debug, Encode)] pub enum TypeDef { /// A composite type (e.g. a struct or a tuple) Composite(TypeDefComposite), @@ -200,9 +199,10 @@ impl IntoPortable for TypeDef { } /// A primitive Rust type. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)] pub enum TypeDefPrimitive { /// `bool` type Bool, @@ -237,8 +237,9 @@ pub enum TypeDefPrimitive { } /// An array type. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)] pub struct TypeDefArray { /// The length of the array type. len: u32, @@ -291,7 +292,8 @@ where )) )] #[cfg_attr(feature = "serde", serde(transparent))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)] pub struct TypeDefTuple { /// The types of the tuple fields. fields: Vec, @@ -336,7 +338,8 @@ where /// A type to refer to a sequence of elements of the same type. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)] pub struct TypeDefSequence { /// The element type of the sequence type. #[cfg_attr(feature = "serde", serde(rename = "type"))] @@ -384,8 +387,9 @@ where } /// A type wrapped in [`Compact`]. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)] pub struct TypeDefCompact { /// The type wrapped in [`Compact`], i.e. the `T` in `Compact`. #[cfg_attr(feature = "serde", serde(rename = "type"))] @@ -429,7 +433,8 @@ where /// required to explicitly skip fields that cannot be represented in SCALE /// encoding, using the `#[codec(skip)]` attribute. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Debug)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)] pub struct TypeDefPhantom { /// The PhantomData type parameter #[cfg_attr(feature = "serde", serde(rename = "type"))] diff --git a/src/ty/path.rs b/src/ty/path.rs index 36ce7263..4df862ee 100644 --- a/src/ty/path.rs +++ b/src/ty/path.rs @@ -32,10 +32,7 @@ use crate::{ IntoPortable, Registry, }; -use scale::{ - Decode, - Encode, -}; +use scale::Encode; #[cfg(feature = "serde")] use serde::{ de::DeserializeOwned, @@ -50,7 +47,6 @@ use serde::{ /// has been defined. The last /// /// Rust prelude type may have an empty namespace definition. -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde", @@ -60,6 +56,8 @@ use serde::{ )) )] #[cfg_attr(feature = "serde", serde(transparent))] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Encode)] pub struct Path { /// The segments of the namespace. segments: Vec, diff --git a/src/ty/variant.rs b/src/ty/variant.rs index 75456ed4..b201fc66 100644 --- a/src/ty/variant.rs +++ b/src/ty/variant.rs @@ -26,10 +26,7 @@ use crate::{ Registry, }; use derive_more::From; -use scale::{ - Decode, - Encode, -}; +use scale::Encode; #[cfg(feature = "serde")] use serde::{ de::DeserializeOwned, @@ -84,7 +81,8 @@ use serde::{ )) )] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, From, Encode, Decode)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, From, Encode)] pub struct TypeDefVariant { /// The variants of a variant type #[cfg_attr( @@ -149,7 +147,8 @@ where deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned", )) )] -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Encode, Decode)] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Encode)] pub struct Variant { /// The name of the variant. name: T::String, diff --git a/test_suite/tests/codec.rs b/test_suite/tests/codec.rs index 64efc3e4..cfe41a97 100644 --- a/test_suite/tests/codec.rs +++ b/test_suite/tests/codec.rs @@ -62,7 +62,7 @@ fn scale_encode_then_decode_to_readonly() { let mut encoded = registry.encode(); let original_serialized = serde_json::to_value(registry).unwrap(); - let readonly_decoded = PortableRegistry::::decode(&mut &encoded[..]).unwrap(); + let readonly_decoded = PortableRegistry::decode(&mut &encoded[..]).unwrap(); assert!(readonly_decoded .resolve(NonZeroU32::new(1).unwrap()) .is_some()); @@ -79,7 +79,7 @@ fn json_serialize_then_deserialize_to_readonly() { let registry: PortableRegistry = registry.into(); let original_serialized = serde_json::to_value(registry).unwrap(); // assert_eq!(original_serialized, serde_json::Value::Null); - let readonly_deserialized: PortableRegistry = + let readonly_deserialized: PortableRegistry = serde_json::from_value(original_serialized.clone()).unwrap(); assert!(readonly_deserialized .resolve(NonZeroU32::new(1).unwrap())