Skip to content

Commit 9ab6585

Browse files
committed
chore: docs
1 parent de38c8f commit 9ab6585

6 files changed

Lines changed: 134 additions & 180 deletions

File tree

libs/@local/hashql/core/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,3 @@ harness = false
6464
[[bench]]
6565
name = "bit_matrix"
6666
harness = false
67-
68-
[[bench]]
69-
name = "stdlib"
70-
harness = false

libs/@local/hashql/core/benches/stdlib.rs

Lines changed: 0 additions & 99 deletions
This file was deleted.

libs/@local/hashql/core/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
sync_nonpoison,
4040
try_trait_v2,
4141
variant_count,
42-
iter_collect_into,
4342
maybe_uninit_fill
4443
)]
4544

libs/@local/hashql/core/src/module/mod.rs

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ impl ModuleId {
3838
pub const ROOT: Self = Self::MAX;
3939
}
4040

41+
/// A builder for constructing a [`ModuleRegistry`].
42+
///
43+
/// Collects module definitions during construction (e.g. stdlib registration) and produces
44+
/// an immutable [`ModuleRegistry`] via [`finish`].
45+
///
46+
/// The typical construction sequence is:
47+
/// 1. Create with [`new_in`]
48+
/// 2. Provision module IDs with [`provision_module`]
49+
/// 3. Insert fully built modules with [`insert_module`]
50+
/// 4. Register root-level modules with [`register`]
51+
/// 5. Finalize into a [`ModuleRegistry`] with [`finish`]
52+
///
53+
/// [`new_in`]: Self::new_in
54+
/// [`provision_module`]: Self::provision_module
55+
/// [`insert_module`]: Self::insert_module
56+
/// [`register`]: Self::register
57+
/// [`finish`]: Self::finish
4158
pub struct PartialModuleRegistry<'heap, S: Allocator> {
4259
heap: &'heap Heap,
4360
modules: IdVec<ModuleId, Option<Module<'heap>>, S>,
@@ -54,16 +71,22 @@ impl<'heap, S: Allocator> PartialModuleRegistry<'heap, S> {
5471
}
5572
}
5673

74+
/// Reserves a fresh [`ModuleId`] that can be referenced by child items before the
75+
/// module itself is inserted.
5776
pub fn provision_module(&mut self) -> ModuleId {
5877
self.modules.push(None)
5978
}
6079

61-
/// Interns a new module into the registry.
80+
/// Inserts a fully constructed module into the registry.
81+
///
82+
/// The module's `id` must have been previously obtained from [`provision_module`].
6283
///
6384
/// # Panics
6485
///
65-
/// In debug builds, this function will panic if any item in the module has a parent
66-
/// that doesn't match the module ID.
86+
/// In debug builds, panics if any item in the module references a different module ID
87+
/// than the one being inserted, or if child module metadata is inconsistent.
88+
///
89+
/// [`provision_module`]: Self::provision_module
6790
pub fn insert_module(&mut self, module: Module<'heap>) {
6891
#[cfg(debug_assertions)]
6992
{
@@ -88,11 +111,13 @@ impl<'heap, S: Allocator> PartialModuleRegistry<'heap, S> {
88111
debug_assert!(value.is_none());
89112
}
90113

91-
/// Register a new module in the root namespace.
114+
/// Registers a module in the root namespace, making it accessible by name.
92115
///
93116
/// # Panics
94117
///
95-
/// This function will panic if the internal `RwLock` is poisoned.
118+
/// Panics if the module has not been inserted via [`insert_module`].
119+
///
120+
/// [`insert_module`]: Self::insert_module
96121
pub fn register(&mut self, module: ModuleId) {
97122
let module = self
98123
.modules
@@ -104,6 +129,13 @@ impl<'heap, S: Allocator> PartialModuleRegistry<'heap, S> {
104129
self.root.insert(module.name, module.id);
105130
}
106131

132+
/// Finalizes the builder into an immutable [`ModuleRegistry`].
133+
///
134+
/// # Panics
135+
///
136+
/// Panics if any provisioned module ID was never populated via [`insert_module`].
137+
///
138+
/// [`insert_module`]: Self::insert_module
107139
#[expect(unsafe_code)]
108140
pub fn finish(self, heap: &'heap Heap) -> ModuleRegistry<'heap> {
109141
assert!(
@@ -146,6 +178,16 @@ pub struct ModuleRegistry<'heap> {
146178
}
147179

148180
impl<'heap> ModuleRegistry<'heap> {
181+
/// Creates a new module registry with the standard library pre-loaded.
182+
///
183+
/// This initializes the registry with all the standard modules and items
184+
/// defined in the standard library, using the global allocator for scratch space.
185+
pub fn new(env: &Environment<'heap>) -> Self {
186+
Self::new_in(env, alloc::alloc::Global)
187+
}
188+
189+
/// Creates a new module registry with the standard library pre-loaded, using `scratch`
190+
/// for temporary allocations during construction.
149191
pub fn new_in<S: Allocator + Clone>(env: &Environment<'heap>, scratch: S) -> Self {
150192
let mut partial = PartialModuleRegistry::new_in(env.heap, scratch.clone());
151193

@@ -155,11 +197,7 @@ impl<'heap> ModuleRegistry<'heap> {
155197
partial.finish(env.heap)
156198
}
157199

158-
/// Find an item by name in the root namespace.
159-
///
160-
/// # Panics
161-
///
162-
/// This function will panic if the internal `RwLock` is poisoned.
200+
/// Looks up a root-level module by name.
163201
#[must_use]
164202
pub fn find_by_name(&self, name: Symbol<'heap>) -> Option<Module<'heap>> {
165203
let id = self.root.get(&name).copied()?;
@@ -389,3 +427,49 @@ impl HasId for Module<'_> {
389427
self.id
390428
}
391429
}
430+
431+
#[cfg(test)]
432+
impl<'heap> ModuleRegistry<'heap> {
433+
/// Creates a partially built registry with the stdlib loaded.
434+
///
435+
/// Returns a `PartialModuleRegistry` that can be further customized (e.g. by inserting
436+
/// test modules) before calling [`PartialModuleRegistry::finish`].
437+
pub(crate) fn builder(
438+
env: &Environment<'heap>,
439+
) -> PartialModuleRegistry<'heap, alloc::alloc::Global> {
440+
use alloc::alloc::Global;
441+
442+
let mut partial = PartialModuleRegistry::new_in(env.heap, Global);
443+
444+
let mut std = StandardLibrary::new(env, &mut partial, Global);
445+
std.register();
446+
447+
partial
448+
}
449+
}
450+
451+
#[cfg(test)]
452+
impl<'heap, S: Allocator> PartialModuleRegistry<'heap, S> {
453+
/// Inserts a root-level module with the given name and items.
454+
///
455+
/// This is a test helper that provisions a module ID, passes it to the `items` closure
456+
/// so items can reference their owning module, then inserts and registers the module.
457+
pub(crate) fn insert_root_module(
458+
&mut self,
459+
name: Symbol<'heap>,
460+
items: impl FnOnce(ModuleId) -> &'heap [Item<'heap>],
461+
) -> ModuleId {
462+
let id = self.provision_module();
463+
464+
self.insert_module(Module {
465+
id,
466+
name,
467+
parent: ModuleId::ROOT,
468+
depth: const { NonZero::new(1).unwrap() },
469+
items: items(id),
470+
});
471+
self.register(id);
472+
473+
id
474+
}
475+
}

0 commit comments

Comments
 (0)