Skip to content

Commit

Permalink
Include type id in serialized type registry (#114)
Browse files Browse the repository at this point in the history
* Include type id in serialized type registry

* Fmt

* Fix json tests

* Make type lookup id compact
  • Loading branch information
ascjones authored Jul 16, 2021
1 parent 0a9f271 commit 244f7ab
Show file tree
Hide file tree
Showing 3 changed files with 290 additions and 197 deletions.
1 change: 1 addition & 0 deletions src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use serde::{
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct UntrackedSymbol<T> {
/// The index to the symbol in the interner table.
#[codec(compact)]
id: u32,
#[cfg_attr(feature = "serde", serde(skip))]
marker: PhantomData<fn() -> T>,
Expand Down
55 changes: 42 additions & 13 deletions src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,29 +164,58 @@ impl Registry {
#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
#[derive(Clone, Debug, PartialEq, Eq, Encode)]
pub struct PortableRegistry {
types: Vec<Type<PortableForm>>,
types: Vec<PortableType>,
}

impl From<Registry> for PortableRegistry {
fn from(registry: Registry) -> Self {
PortableRegistry {
types: registry.types.values().cloned().collect::<Vec<_>>(),
types: registry
.types
.iter()
.map(|(k, v)| {
PortableType {
id: k.id(),
ty: v.clone(),
}
})
.collect::<Vec<_>>(),
}
}
}

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<PortableForm>> {
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<Item = (u32, &Type<PortableForm>)> {
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<PortableForm>,
}

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<PortableForm> {
&self.ty
}
}

Expand All @@ -202,19 +231,19 @@ mod tests {
};

#[test]
fn readonly_enumerate() {
fn readonly_type_ids() {
let mut registry = Registry::new();
registry.register_type(&MetaType::new::<u32>());
registry.register_type(&MetaType::new::<bool>());
registry.register_type(&MetaType::new::<Option<(u32, bool)>>());

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;
}
}
Expand Down
Loading

0 comments on commit 244f7ab

Please sign in to comment.