Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Construct PortableRegistry dynamically at runtime #164

Merged
merged 51 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8345a3c
WIP: allow constructing MetaTypes at runtime
ascjones Aug 11, 2022
3a14663
Remove fmt config options
ascjones Aug 11, 2022
1e03bd3
Add some docs
ascjones Aug 11, 2022
a68f28c
std feature String
ascjones Aug 11, 2022
da92e9d
fully qualified String
ascjones Aug 11, 2022
592736a
Fix features build
ascjones Aug 11, 2022
4500520
Generic string parameter for MetaType
ascjones Aug 15, 2022
a08ef8a
Remove license_template_path
ascjones Aug 15, 2022
3cacf78
Fmt
ascjones Aug 15, 2022
6476671
Fix fmt
ascjones Aug 15, 2022
6a1343b
Replace MetaFormString trait with cfg based string
ascjones Aug 16, 2022
42db0e3
Remove unused into
ascjones Aug 16, 2022
0c525c6
Fix more errors
ascjones Aug 16, 2022
7dfe55b
Now string types are the same across Meta/Portable, no longer necessa…
ascjones Aug 17, 2022
54ff5fc
Remove custom MetaType and TypeId
ascjones Aug 22, 2022
16e4e79
EXPERIMENT: make all type def fields public to allow construting Port…
ascjones Aug 22, 2022
c46186d
Rename test
ascjones Aug 22, 2022
5b47b1b
Fix up type ids in test
ascjones Aug 22, 2022
40b6047
Fix ui test
ascjones Aug 22, 2022
8255c99
*TEMPORARILY* pub registry for PortableType
ascjones Aug 23, 2022
79c19a9
add constructor for portableregistry
xermicus Aug 28, 2022
d8c3b5e
constructor for PortableType
xermicus Aug 28, 2022
0e4737f
implement remaining constructors for generic Form
xermicus Aug 28, 2022
8319875
make Type::new constructor public
xermicus Aug 28, 2022
ef4c3ee
make remaining constructor public
xermicus Aug 28, 2022
9e48542
add a new custom constructor for path
xermicus Sep 22, 2022
b900f54
Merge branch 'master' into aj/custom-meta-types
xermicus Sep 22, 2022
0b45a89
use new_custom in a test
xermicus Sep 22, 2022
6694dc0
Remove not required builder fn for MetaType
ascjones Sep 22, 2022
83a80ef
WIP propogate Form through builders
ascjones Oct 4, 2022
ae22be7
Fix up path builders
ascjones Oct 4, 2022
ababa57
More fixes
ascjones Oct 4, 2022
383399c
Fix up generated From impls
ascjones Oct 4, 2022
221c2f9
Fix up field builders
ascjones Oct 4, 2022
6caa3d6
Fix up field builder methods for MetaForm
ascjones Oct 4, 2022
a36540a
Rename constructor
ascjones Oct 4, 2022
b027ae8
Hide pub fields and add portable builder helper methods
ascjones Oct 4, 2022
1de0508
Fmt
ascjones Oct 4, 2022
f04d4ef
Explicity export PortableType
ascjones Oct 4, 2022
23c6cb9
Clippy
ascjones Oct 4, 2022
590bc58
Move PortableRegistry to own file, introduce PortableRegistryBuilder
ascjones Oct 5, 2022
b5b5a6f
Remove some stray `Str` type params
ascjones Oct 5, 2022
3c9d8dd
Implement PortableRegistryBuilder to manage ids
ascjones Oct 5, 2022
a2668a9
Default impl for PortableRegistryBuilder
ascjones Oct 5, 2022
220a59d
implement getter for registered types in PortableRegistryBuilder
xermicus Oct 6, 2022
07057ce
Rename new path constructor
ascjones Oct 7, 2022
07aaef8
Rename new_custom methods to new_portable
ascjones Oct 7, 2022
192d12c
Revert reordering of MetaForm
ascjones Oct 7, 2022
403c720
Move path construction back to MetaForm for non-breaking changes
ascjones Oct 7, 2022
1044c8d
Update path tests
ascjones Oct 7, 2022
c9149c2
TypeParameter::new_portable for non breaking change
ascjones Oct 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement PortableRegistryBuilder to manage ids
  • Loading branch information
ascjones committed Oct 5, 2022
commit 3c9d8dd4af746d97e37802fae9a66010dcc50f43
7 changes: 6 additions & 1 deletion src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pub struct Interner<T> {
///
/// This is used to efficiently provide access to the cached elements and
/// to establish a strict ordering upon them since each is uniquely
/// idenfitied later by its position in the vector.
/// identified later by its position in the vector.
vec: Vec<T>,
}

Expand Down Expand Up @@ -198,6 +198,11 @@ where
}
self.vec.get(idx)
}

/// Returns the ordered sequence of interned elements.
pub fn elements(&self) -> &[T] {
&self.vec
}
}

#[cfg(test)]
Expand Down
100 changes: 69 additions & 31 deletions src/portable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

use crate::{
form::PortableForm,
interner::Interner,
prelude::{
fmt::Debug,
vec::Vec,
Expand Down Expand Up @@ -60,11 +61,6 @@ impl From<Registry> for PortableRegistry {
}

impl PortableRegistry {
/// Construct a new `PortableRegistry` from custom types.
pub fn new_from_types(types: Vec<PortableType>) -> Self {
Self { types }
}

/// 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).map(|ty| ty.ty())
Expand Down Expand Up @@ -106,18 +102,60 @@ impl PortableType {
}

/// Construct a [`PortableRegistry`].
///
/// Guarantees that the resulting [`PortableRegistry`] has the list of types in the correct order,
/// since downstream libs assume that a `u32` type id corresponds to the index of the type
/// definition type table.
pub struct PortableRegistryBuilder {
types: Interner<Type<PortableForm>>,
}

impl PortableRegistryBuilder {
/// Create a new [`PortableRegistryBuilder`].
pub fn new() -> Self {
Self {
types: Default::default(),
}
}

/// Register a type, returning the assigned ID.
///
/// If the type is already registered it will return the existing ID.
pub fn register_type(&mut self, ty: Type<PortableForm>) -> u32 {
self.types.intern_or_get(ty).1.into_untracked().id()
}

/// Returns the type id that would be assigned to a newly registered type.
pub fn next_type_id(&self) -> u32 {
self.types.elements().len() as u32
}

/// Finalize and return a valid [`PortableRegistry`] instance.
pub fn finish(&self) -> PortableRegistry {
let types = self
.types
.elements()
.iter()
.enumerate()
.map(|(i, ty)| {
PortableType {
id: i as u32,
ty: ty.clone(),
}
})
.collect();
PortableRegistry { types }
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::{
build::*,
prelude::vec,
*,
};
use super::*;

#[test]
fn type_ids_are_sequential() {
Expand All @@ -137,39 +175,39 @@ mod tests {

#[test]
fn construct_portable_registry() {
let mut types = Vec::new();

let u32_type_id = types.len() as u32;
types.push(PortableType::new(
u32_type_id,
Type::new(Path::default(), vec![], TypeDefPrimitive::U32, vec![]),
));

let vec_u32_type_id = types.len() as u32;
types.push(PortableType::new(
vec_u32_type_id,
Type::new(
Path::default(),
vec![],
TypeDefSequence::new(u32_type_id.into()),
vec![],
),
));

let composite_type_id = types.len() as u32;
let composite = Type::builder_portable()
let mut builder = PortableRegistryBuilder::new();
let u32_type = Type::new(Path::default(), vec![], TypeDefPrimitive::U32, vec![]);
let u32_type_id = builder.register_type(u32_type.clone());

let vec_u32_type = Type::new(
Path::default(),
vec![],
TypeDefSequence::new(u32_type_id.into()),
vec![],
);
let vec_u32_type_id = builder.register_type(vec_u32_type.clone());

let self_referential_type_id = builder.next_type_id();

let composite_type = Type::builder_portable()
.path(Path::new_custom(vec!["MyStruct".into()]))
.composite(
Fields::named()
.field_portable(|f| f.name("primitive".into()).ty(u32_type_id))
.field_portable(|f| f.name("vec_of_u32".into()).ty(vec_u32_type_id))
.field_portable(|f| {
f.name("self_referential".into()).ty(composite_type_id)
f.name("self_referential".into())
.ty(self_referential_type_id)
}),
);
types.push(PortableType::new(composite_type_id, composite));
let composite_type_id = builder.register_type(composite_type.clone());

assert_eq!(self_referential_type_id, composite_type_id);

let _registry = PortableRegistry::new_from_types(types);
let registry = builder.finish();

assert_eq!(Some(&u32_type), registry.resolve(u32_type_id));
assert_eq!(Some(&vec_u32_type), registry.resolve(vec_u32_type_id));
assert_eq!(Some(&composite_type), registry.resolve(composite_type_id));
}
}

4 changes: 3 additions & 1 deletion src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ impl Registry {
}

/// Returns an iterator over the types with their keys
pub fn types(&self) -> impl Iterator<Item = (&UntrackedSymbol<TypeId>, &Type<PortableForm>)> {
pub fn types(
&self,
) -> impl Iterator<Item = (&UntrackedSymbol<TypeId>, &Type<PortableForm>)> {
self.types.iter()
}
}
Expand Down