rusty_alto/ids.rs
1//! Compact IDs for automaton states, ranked symbols, and arities.
2
3use std::fmt;
4
5/// Dense integer identifier for an automaton state.
6///
7/// `StateId` is the fast state representation used by [`crate::Explicit`],
8/// [`crate::Memo`], and deterministic runners. IDs are dense, starting at zero,
9/// so they can be used to index vectors and bitsets.
10///
11/// Most users should create states with [`crate::ExplicitBuilder::new_state`]
12/// or [`crate::Interner::intern`] rather than constructing `StateId` directly.
13/// The one special value is [`StateId::STUCK`], which is reserved for rejected
14/// subtrees and must not be used as an ordinary state.
15#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
16pub struct StateId(pub u32);
17
18impl StateId {
19 /// Sentinel meaning "this subtree has no valid state".
20 ///
21 /// Deterministic runs store this value in their side table when a node is
22 /// rejected. Builders and interners never allocate it as a real state.
23 pub const STUCK: StateId = StateId(u32::MAX);
24
25 /// Convert this state ID to a vector or bitset index.
26 ///
27 /// Do not call this on [`StateId::STUCK`] unless the surrounding code has
28 /// explicitly chosen to handle the sentinel as `usize::MAX`.
29 pub fn index(self) -> usize {
30 self.0 as usize
31 }
32
33 /// Return whether this ID is the stuck sentinel.
34 pub fn is_stuck(self) -> bool {
35 self == Self::STUCK
36 }
37}
38
39impl fmt::Debug for StateId {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 if self.is_stuck() {
42 f.write_str("StateId::STUCK")
43 } else {
44 f.debug_tuple("StateId").field(&self.0).finish()
45 }
46 }
47}
48
49/// Identifier for a node label or grammar symbol.
50///
51/// The library deliberately does not intern or interpret symbols. Your
52/// application owns the signature and maps labels such as `"a"` or `"concat"`
53/// to `Symbol` values.
54#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Default)]
55pub struct Symbol(pub u32);
56
57/// Number of children a symbol expects.
58///
59/// `Arity` appears mainly in [`crate::materialize()`], where the caller provides
60/// the finite alphabet to explore.
61pub type Arity = u8;