Skip to content

Commit

Permalink
fix: calling Compiler.new_namespace for a second time with the same…
Browse files Browse the repository at this point in the history
… name should not have effect

When `Compiler.new_namespace` is called two consecutive times with the same namespace, the second call has not effect.
  • Loading branch information
plusvic committed Sep 13, 2024
1 parent 755213e commit d7db62b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
16 changes: 13 additions & 3 deletions lib/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ pub struct Compiler<'a> {
/// Pool that contains all the identifiers used in the rules. Each
/// identifier appears only once, even if they are used by multiple
/// rules. For example, the pool contains a single copy of the common
/// identifier `$a`. Each identifier have an unique 32-bits [`IdentId`]
/// identifier `$a`. Each identifier have a unique 32-bits [`IdentId`]
/// that can be used for retrieving the identifier from the pool.
ident_pool: StringPool<IdentId>,

Expand Down Expand Up @@ -611,7 +611,8 @@ impl<'a> Compiler<'a> {
/// Creates a new namespace.
///
/// Further calls to [`Compiler::add_source`] will put the rules under the
/// newly created namespace.
/// newly created namespace. If the current namespace is already named as
/// the current one, no new namespace is created.
///
/// In the example below both rules `foo` and `bar` are put into the same
/// namespace (the default namespace), therefore `bar` can use `foo` as
Expand Down Expand Up @@ -643,7 +644,16 @@ impl<'a> Compiler<'a> {
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn new_namespace(&mut self, namespace: &str) -> &mut Self {
// Remove the symbol table corresponding to the previous namespace.
let current_namespace = self
.ident_pool
.get(self.current_namespace.ident_id)
.expect("expecting a namespace");
// If the current namespace is already named as the new namespace
// this function has no effect.
if namespace == current_namespace {
return self;
}
// Remove the symbol table corresponding to the current namespace.
self.symbol_table.pop().expect("expecting a namespace");
// Create a new namespace. The NamespaceId is simply the ID of the
// previous namespace + 1.
Expand Down
12 changes: 12 additions & 0 deletions lib/src/compiler/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ fn namespaces() {
.new_namespace("bar")
.add_source("rule bar {condition: foo}")
.is_err());

let mut compiler = Compiler::new();

// `bar` can use `foo` because they are in the same namespace, the second
// call to `new_namespace` has no effect.
assert!(compiler
.new_namespace("foo")
.add_source("rule foo {condition: true}")
.unwrap()
.new_namespace("foo")
.add_source("rule bar {condition: foo}")
.is_ok());
}

#[test]
Expand Down

0 comments on commit d7db62b

Please sign in to comment.