table.rs
Overview
This file defines a generic data structure, BitmasksTable<TBitsSource, TTarget>, which manages a collection of bitmask-to-target mappings. It allows for efficient pattern matching of bit patterns (TBitsSource) against defined bitmasks, returning a corresponding target value (TTarget). The table ensures that there is always a default fallback rule that matches any bit pattern, preventing unmatched cases.
The primary purpose is to store and query ordered bitmask rules, where each bitmask represents a pattern of bits to match, and the associated target is a value or identifier linked to that pattern. This structure is useful in scenarios where decisions or routing depend on bit-level pattern matching.
The file depends on the Bitmask type from the mask module, which encapsulates bitmask logic and matching. It also uses third-party crates such as anyhow for error handling and serde for serialization.
Types and Structures
BitmasksTable<TBitsSource, TTarget>
A generic table storing an ordered list of pairs (Bitmask<TBitsSource>, TTarget). This table is designed to:
Store multiple bitmask rules, each mapping a bit pattern to a target value.
Always include a default rule at the end, matching all inputs not covered by previous rules.
Find the first matching target for a given bit pattern efficiently.
Allow insertion and removal of rules, with restrictions on manipulating the default rule.
Type Parameters:
TBitsSource: The type representing the bit pattern source. It must support equality, cloning, default construction, debugging, and bitwise AND operations.TTarget: The type representing the target value associated with each bitmask. It must support cloning, default construction, debugging, and equality.
Fields:
masks: A vector of tuples(Bitmask<TBitsSource>, TTarget), ordered by priority. The last element is always the default rule.
Trait Implementations
Default for BitmasksTable
This implementation delegates the default construction to the new method, which initializes a table with a single default rule using default values for both bitmask and target.
Methods
new() -> Self
Creates a new BitmasksTable with a single default rule at the end. The default rule uses the default bitmask (matching all inputs) and the default target value.
Usage example:
let table: BitmasksTable<u16, u8> = BitmasksTable::new();
rows(&self) -> impl Iterator<Item = &(Bitmask<TBitsSource>, TTarget)>
Returns an iterator over all the (Bitmask, Target) pairs in the table, in order.
Usage example:
for (bitmask, target) in table.rows() {
println!("{:?} -> {:?}", bitmask, target);
}
find_match(&self, bits: &TBitsSource) -> TTarget
Scans the table from top to bottom and returns a clone of the target associated with the first bitmask that matches the given bits. The method panics if no match is found, which should not happen due to the presence of the default rule.
Parameters:
bits: Reference to the bit pattern to match.
Returns:
A clone of the matched target value.
Usage example:
let target = table.find_match(&some_bits);
is_match(&self, bits: &TBitsSource, target: TTarget) -> bool
Checks if the given bits match the specified target by internally finding the matched target and comparing it.
Parameters:
bits: Reference to the bit pattern to match.target: The target value to compare against.
Returns:
trueif the matched target equals the providedtarget, otherwisefalse.
insert_above(&mut self, row_index: usize, mask: Bitmask<TBitsSource>, thread: TTarget) -> anyhow::Result<()>
Inserts a new bitmask-target rule just above the specified row_index. This allows ordered insertion of rules with priority.
Parameters:
row_index: The position above which the new rule will be inserted.mask: TheBitmaskinstance defining the pattern to match.thread: The target value associated with the mask.
Returns:
Ok(())on success.An error if trying to insert below the default row or if
row_indexis out of bounds.
Usage example:
table.insert_above(0, some_bitmask, some_target)?;
remove(&mut self, row_index: usize) -> anyhow::Result<(Bitmask<TBitsSource>, TTarget)>
Removes the rule at the specified row_index and returns it. Removing the default rule (the last one) is forbidden and returns an error.
Parameters:
row_index: Index of the rule to remove.
Returns:
Ok((Bitmask, Target))tuple of the removed rule.An error if attempting to remove the default rule or if
row_indexis out of bounds.
len(&self) -> usize
Returns the number of rules currently in the table, including the default rule.
Important Implementation Details
The table always maintains a default rule at the bottom, which matches all bit patterns. This ensures that
find_matchnever fails to return a target.The
insert_abovemethod forbids insertion below the default rule (i.e., at the last index), preserving the default rule's position.The
removemethod forbids removing the default rule, ensuring the table always has a fallback.The bitmask matching is performed by the
Bitmask::is_matchmethod from the importedBitmasktype.The generic constraints on
TBitsSourceandTTargetensure that bitwise AND operations and equality comparisons work correctly on bit patterns, which is necessary for pattern matching.
Interaction with Other Parts of the System
Uses the
Bitmask<TBitsSource>struct from the siblingmaskmodule, which encapsulates bitmask construction and matching logic.Relies on the
anyhowcrate for error handling with theensure!macro.Supports serialization and deserialization through the
serdecrate, enabling the table to be saved or loaded.The tests demonstrate usage patterns and verify the correctness of insertion, removal, matching, and the preservation of the default rule.
Usage Context
BitmasksTable can be used in systems that require:
Rule-based routing or dispatch based on bit patterns.
Efficient lookup of targets associated with complex bitmask conditions.
Maintaining ordered priority of rules with fallback defaults.
Example Usage Snippet
use table::BitmasksTable;
use mask::Bitmask;
let mut table = BitmasksTable::<u16, u8>::new();
let mask = Bitmask::<u16>::builder()
.meaningful_mask_bits(!0u16) // all bits considered
.mask_bits(0b0100_0000_0000_0000)
.build();
table.insert_above(0, mask, 1).unwrap();
let matched_target = table.find_match(&0b0100_0000_0000_0000);
assert_eq!(matched_target, 1);
Mermaid Diagram: Class Structure of BitmasksTable
classDiagram
class BitmasksTable {
-masks: Vec<(Bitmask<TBitsSource>, TTarget)>
+new()
+rows()
+find_match()
+is_match()
+insert_above()
+remove()
+len()
}
This diagram shows the core data structure and its public methods, encapsulating the bitmask-to-target mapping logic.