diff --git a/src/interner.rs b/src/interner.rs index c002e2f9..d928d49b 100644 --- a/src/interner.rs +++ b/src/interner.rs @@ -48,6 +48,7 @@ use serde::{ #[cfg_attr(feature = "serde", serde(transparent))] pub struct UntrackedSymbol { /// The index to the symbol in the interner table. + #[codec(compact)] id: u32, #[cfg_attr(feature = "serde", serde(skip))] marker: PhantomData T>, diff --git a/src/registry.rs b/src/registry.rs index a461caff..b075952a 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -164,13 +164,22 @@ impl Registry { #[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] #[derive(Clone, Debug, PartialEq, Eq, Encode)] pub struct PortableRegistry { - types: Vec>, + types: Vec, } impl From for PortableRegistry { fn from(registry: Registry) -> Self { PortableRegistry { - types: registry.types.values().cloned().collect::>(), + types: registry + .types + .iter() + .map(|(k, v)| { + PortableType { + id: k.id(), + ty: v.clone(), + } + }) + .collect::>(), } } } @@ -178,15 +187,35 @@ impl From for PortableRegistry { impl PortableRegistry { /// Returns the type definition for the given identifier, `None` if no type found for that ID. pub fn resolve(&self, id: u32) -> Option<&Type> { - self.types.get(id as usize) + self.types.get(id as usize).map(|ty| ty.ty()) } - /// Returns an iterator for all types paired with their associated u32 identifier. - pub fn enumerate(&self) -> impl Iterator)> { - self.types.iter().enumerate().map(|(i, ty)| { - let id = i as u32; - (id, ty) - }) + /// Returns all types with their associated identifiers. + pub fn types(&self) -> &[PortableType] { + &self.types + } +} + +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(all(feature = "serde", feature = "decode"), derive(serde::Deserialize))] +#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))] +#[derive(Clone, Debug, PartialEq, Eq, Encode)] +pub struct PortableType { + #[codec(compact)] + id: u32, + #[cfg_attr(feature = "serde", serde(rename = "type"))] + ty: Type, +} + +impl PortableType { + /// Returns the index of the [`PortableType`]. + pub fn id(&self) -> u32 { + self.id + } + + /// Returns the type of the [`PortableType`]. + pub fn ty(&self) -> &Type { + &self.ty } } @@ -202,7 +231,7 @@ mod tests { }; #[test] - fn readonly_enumerate() { + fn readonly_type_ids() { let mut registry = Registry::new(); registry.register_type(&MetaType::new::()); registry.register_type(&MetaType::new::()); @@ -210,11 +239,11 @@ mod tests { let readonly: PortableRegistry = registry.into(); - assert_eq!(4, readonly.enumerate().count()); + assert_eq!(4, readonly.types().len()); let mut expected = 0; - for (i, _) in readonly.enumerate() { - assert_eq!(expected, i); + for ty in readonly.types() { + assert_eq!(expected, ty.id()); expected += 1; } } diff --git a/test_suite/tests/json.rs b/test_suite/tests/json.rs index 2ef0f895..7717f7a1 100644 --- a/test_suite/tests/json.rs +++ b/test_suite/tests/json.rs @@ -426,31 +426,37 @@ fn test_recursive_type_with_box() { let expected_json = json!({ "types": [ { - "path": ["json", "Tree"], - "def": { - "variant": { - "variants": [ - { - "name": "Leaf", - "index": 0, - "fields": [ - { "name": "value", "type": 1, "typeName": "i32" }, - ], - }, - { - "name": "Node", - "index": 1, - "fields": [ - { "name": "right", "type": 0, "typeName": "Box" }, - { "name": "left", "type": 0, "typeName": "Box" }, - ], - } - ], - }, + "id": 0, + "type": { + "path": ["json", "Tree"], + "def": { + "variant": { + "variants": [ + { + "name": "Leaf", + "index": 0, + "fields": [ + { "name": "value", "type": 1, "typeName": "i32" }, + ], + }, + { + "name": "Node", + "index": 1, + "fields": [ + { "name": "right", "type": 0, "typeName": "Box" }, + { "name": "left", "type": 0, "typeName": "Box" }, + ], + } + ], + }, + } } }, { - "def": { "primitive": "i32" }, + "id": 1, + "type": { + "def": { "primitive": "i32" }, + } }, ] }); @@ -476,37 +482,64 @@ fn registry_knows_about_compact_types() { let expected_json = json!({ "types": [ - { // type 1 - "path": ["json", "Dense"], - "def": { - "composite": { - "fields": [ - { "name": "a", "type": 1, "typeName": "u128" }, - { "name": "a_not_compact", "type": 2, "typeName": "u128" }, - { "name": "b", "type": 3, "typeName": "[u8; 32]" }, - { "name": "c", "type": 5, "typeName": "u64" } - ] + { + "id": 0, + "type": { + "path": ["json", "Dense"], + "def": { + "composite": { + "fields": [ + { "name": "a", "type": 1, "typeName": "u128" }, + { "name": "a_not_compact", "type": 2, "typeName": "u128" }, + { "name": "b", "type": 3, "typeName": "[u8; 32]" }, + { "name": "c", "type": 5, "typeName": "u64" } + ] + } } } }, - { // type 2, the `Compact` of field `a`. - "def": { "compact": { "type": 2 } }, - }, - { // type 3, the `u128` used by type 2 and field `a_not_compact`. - "def": { "primitive": "u128" } + { + "id": 1, + "type": { + // type 1, the `Compact` of field `a`. + "def": { "compact": { "type": 2 } }, + } }, - { // type 4, the `[u8; 32]` of field `b`. - "def": { "array": { "len": 32, "type": 4 }} + { + "id": 2, + "type": { + // type 2, the `u128` used by type 2 and field `a_not_compact`. + "def": { "primitive": "u128" } + } }, - { // type 5, the `u8` in `[u8; 32]` - "def": { "primitive": "u8" } + { + "id": 3, + "type": { + // type 3, the `[u8; 32]` of field `b`. + "def": { "array": { "len": 32, "type": 4 }} + } }, - { // type 6, the `Compact` of field `c` - "def": { "compact": { "type": 6 } }, + { + "id": 4, + "type": { + // type 4, the `u8` in `[u8; 32]` + "def": { "primitive": "u8" } + } }, - { // type 7, the `u64` in `Compact` of field `c` - "def": { "primitive": "u64" } + { + "id": 5, + "type": { + // type 5, the `Compact` of field `c` + "def": { "compact": { "type": 6 } }, + } }, + { + "id": 6, + "type": { + // type 6, the `u64` in `Compact` of field `c` + "def": { "primitive": "u64" } + } + } ] }); @@ -554,163 +587,193 @@ fn test_registry() { let expected_json = json!({ "types": [ - { // type 0 - "path": [ - "json", - "UnitStruct", - ], - "def": { - "composite": {}, + { + "id": 0, + "type": { + "path": [ + "json", + "UnitStruct", + ], + "def": { + "composite": {}, + } } }, - { // type 1 - "path": [ - "json", - "TupleStruct", - ], - "def": { - "composite": { - "fields": [ - { "type": 2, "typeName": "u8" }, - { "type": 3, "typeName": "u32" }, - ], - }, + { + "id": 1, + "type": { + "path": [ + "json", + "TupleStruct", + ], + "def": { + "composite": { + "fields": [ + { "type": 2, "typeName": "u8" }, + { "type": 3, "typeName": "u32" }, + ], + } + } } }, - { // type 2 - "def": { "primitive": "u8" }, - }, - { // type 3 - "def": { "primitive": "u32" }, + { + "id": 2, + "type": { + "def": { "primitive": "u8" } + } }, - { // type 4 - "path": [ - "json", - "Struct", - ], - "def": { - "composite": { - "fields": [ - { - "name": "a", - "type": 2, - "typeName": "u8" - }, - { - "name": "b", - "type": 3, - "typeName": "u32" - }, - { - "name": "c", - "type": 5, - "typeName": "[u8; 32]" - } - ] - }, + { + "id": 3, + "type": { + "def": { "primitive": "u32" } } }, - { // type 5 - "def": { - "array": { - "len": 32, - "type": 2, // u8 - }, + { + "id": 4, + "type": { + "path": [ + "json", + "Struct", + ], + "def": { + "composite": { + "fields": [ + { + "name": "a", + "type": 2, + "typeName": "u8" + }, + { + "name": "b", + "type": 3, + "typeName": "u32" + }, + { + "name": "c", + "type": 5, + "typeName": "[u8; 32]" + } + ] + } + } } }, - { // type 6 - "path": [ - "json", - "RecursiveStruct", - ], - "def": { - "composite": { - "fields": [ - { - "name": "rec", - "type": 7, - "typeName": "Vec" - } - ] - }, + { + "id": 5, + "type": { + "def": { + "array": { + "len": 32, + "type": 2, // u8 + } + } } }, - { // type 7 - "def": { - "sequence": { - "type": 6, // RecursiveStruct - }, + { + "id": 6, + "type": { + "path": [ + "json", + "RecursiveStruct", + ], + "def": { + "composite": { + "fields": [ + { + "name": "rec", + "type": 7, + "typeName": "Vec" + } + ] + } + } } }, - { // type 8 - "path": [ - "json", - "ClikeEnum", - ], - "def": { - "variant": { - "variants": [ - { - "name": "A", - "index": 0, - }, - { - "name": "B", - "index": 1, - }, - { - "name": "C", - "index": 2, - }, - ] + { + "id": 7, + "type": { + "def": { + "sequence": { + "type": 6, // RecursiveStruct + }, } } }, - { // type 9 - "path": [ - "json", - "RustEnum" - ], - "def": { - "variant": { - "variants": [ - { - "name": "A", - "index": 0, - }, - { - "name": "B", - "index": 1, - "fields": [ - { "type": 2, "typeName": "u8" }, // u8 - { "type": 3, "typeName": "u32" }, // u32 - ] - }, - { - "name": "C", - "index": 2, - "fields": [ - { - "name": "a", - "type": 2, // u8 - "typeName": "u8" - }, - { - "name": "b", - "type": 3, // u32 - "typeName": "u32" - }, - { - "name": "c", - "type": 5, - "typeName": "[u8; 32]" - } - ] - } - ] - }, + { + "id": 8, + "type": { + "path": [ + "json", + "ClikeEnum", + ], + "def": { + "variant": { + "variants": [ + { + "name": "A", + "index": 0, + }, + { + "name": "B", + "index": 1, + }, + { + "name": "C", + "index": 2, + }, + ] + } + } } }, + { + "id": 9, + "type": { + "path": [ + "json", + "RustEnum" + ], + "def": { + "variant": { + "variants": [ + { + "name": "A", + "index": 0, + }, + { + "name": "B", + "index": 1, + "fields": [ + { "type": 2, "typeName": "u8" }, // u8 + { "type": 3, "typeName": "u32" }, // u32 + ] + }, + { + "name": "C", + "index": 2, + "fields": [ + { + "name": "a", + "type": 2, // u8 + "typeName": "u8" + }, + { + "name": "b", + "type": 3, // u32 + "typeName": "u32" + }, + { + "name": "c", + "type": 5, + "typeName": "[u8; 32]" + } + ] + } + ] + } + } + } + } ] });