diff --git a/src/form.rs b/src/form.rs index 945c4e76..2e21cd37 100644 --- a/src/form.rs +++ b/src/form.rs @@ -33,6 +33,7 @@ use crate::prelude::{ any::TypeId, fmt::Debug, + marker::PhantomData, string::String, }; @@ -53,9 +54,18 @@ pub trait Form { /// The type representing the type. type Type: PartialEq + Eq + PartialOrd + Ord + Clone + Debug; /// The string type. - type String: PartialEq + Eq + PartialOrd + Ord + Clone + Debug; + type String: FormString; } +/// 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 compact form @@ -78,11 +88,14 @@ impl Form for MetaForm { /// underlying data. /// /// `type String` is owned in order to enable decoding -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] #[cfg_attr(feature = "serde", derive(Serialize))] -pub enum CompactForm {} +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] +pub struct CompactForm(PhantomData); -impl Form for CompactForm { +impl Form for CompactForm +where + S: FormString, +{ type Type = UntrackedSymbol; - type String = String; + type String = S; } diff --git a/src/registry.rs b/src/registry.rs index c5a54153..016f8719 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -27,9 +27,9 @@ use crate::prelude::{ any::TypeId, collections::BTreeMap, + fmt::Debug, mem, num::NonZeroU32, - string::ToString, vec::Vec, }; @@ -37,6 +37,7 @@ use crate::{ form::{ CompactForm, Form, + FormString, }, interner::{ Interner, @@ -51,6 +52,7 @@ use scale::{ }; #[cfg(feature = "serde")] use serde::{ + de::DeserializeOwned, Deserialize, Serialize, }; @@ -68,7 +70,7 @@ impl IntoCompact for &'static str { type Output = ::String; fn into_compact(self, _registry: &mut Registry) -> Self::Output { - self.to_string() + self } } @@ -205,8 +207,15 @@ impl Registry { /// A read-only registry, to be used for decoding/deserializing #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, PartialEq, Eq, Decode)] -pub struct RegistryReadOnly { - types: Vec>, +#[cfg_attr( + feature = "serde", + serde(bound(serialize = "S: Serialize", deserialize = "S: DeserializeOwned")) +)] +pub struct RegistryReadOnly +where + S: FormString, +{ + types: Vec>>, } impl From for RegistryReadOnly { @@ -217,14 +226,17 @@ impl From for RegistryReadOnly { } } -impl RegistryReadOnly { +impl RegistryReadOnly +where + S: FormString, +{ /// 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/test_suite/tests/codec.rs b/test_suite/tests/codec.rs index c6ef0461..6d2f398e 100644 --- a/test_suite/tests/codec.rs +++ b/test_suite/tests/codec.rs @@ -28,6 +28,7 @@ use scale_info::{ form::CompactForm, prelude::{ num::NonZeroU32, + string::String, vec, vec::Vec, }, @@ -60,7 +61,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 = RegistryReadOnly::decode(&mut &encoded[..]).unwrap(); + let readonly_decoded = RegistryReadOnly::::decode(&mut &encoded[..]).unwrap(); assert!(readonly_decoded .resolve(NonZeroU32::new(1).unwrap()) .is_some()); @@ -76,7 +77,7 @@ fn json_serialize_then_deserialize_to_readonly() { let original_serialized = serde_json::to_value(registry).unwrap(); // assert_eq!(original_serialized, serde_json::Value::Null); - let readonly_deserialized: RegistryReadOnly = + let readonly_deserialized: RegistryReadOnly = serde_json::from_value(original_serialized.clone()).unwrap(); assert!(readonly_deserialized .resolve(NonZeroU32::new(1).unwrap())