sipha_core/
traits.rs

1//! Core traits shared by the parsing infrastructure.
2//!
3//! This module defines the fundamental traits that types must implement
4//! to work with sipha parsers:
5//!
6//! - **`TokenKind`**: Types representing token kinds (e.g., keywords, operators)
7//! - **`RuleId`**: Types representing grammar rule identifiers  
8//! - **`NodeId`**: Types representing CST node identifiers
9//! - **`SymbolId`**: Types representing symbol identifiers
10//! - **`GrammarContext`**: Context information passed during parsing
11//! - **`AstNode`**: Types that can be lowered from CST nodes
12//!
13//! # Trait Requirements
14//!
15//! All marker traits (`RuleId`, `NodeId`, `SymbolId`) require:
16//! - `Copy`: Must be copyable (no heap allocation)
17//! - `Eq + Hash`: Must be usable as hash map keys
18//! - `Debug`: Must be debuggable
19//! - `Send + Sync`: Must be thread-safe
20//! - `'static`: Must have no lifetime parameters
21
22use std::{fmt::Debug, hash::Hash};
23
24/// Trait implemented by every token kind enum used by sipha.
25///
26/// The trait bounds guarantee that token kinds can be freely copied, logged,
27/// and used as keys inside hash maps. The [`TokenKind::is_trivia`] hook lets the parser
28/// transparently skip trivia tokens when `include_trivia` is disabled.
29pub trait TokenKind: Copy + Eq + Hash + Debug + Send + Sync + 'static {
30    /// Whether the token should be ignored by default when traversing the
31    /// token stream.
32    fn is_trivia(&self) -> bool;
33}
34
35/// Marker trait implemented by rule identifiers.
36///
37/// This trait has a blanket implementation for all types that satisfy
38/// the required bounds. You typically use an enum for rule identifiers:
39///
40/// ```rust
41/// use sipha_core::traits::RuleId;
42///
43/// #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
44/// enum Rule {
45///     Expr,
46///     Term,
47///     Factor,
48/// }
49///
50/// // RuleId is automatically implemented via blanket impl
51/// ```
52pub trait RuleId: Copy + Eq + Hash + Debug + Send + Sync + 'static {}
53
54/// Marker trait implemented by syntax node identifiers.
55///
56/// Node identifiers are used to reference nodes in the CST arena.
57/// They must be convertible to/from raw indices for arena storage.
58///
59/// # Example
60///
61/// ```rust
62/// use sipha_core::traits::NodeId;
63///
64/// #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
65/// struct MyNodeId(usize);
66///
67/// impl NodeId for MyNodeId {
68///     fn from_raw(raw: usize) -> Self {
69///         MyNodeId(raw)
70///     }
71///
72///     fn to_raw(self) -> usize {
73///         self.0
74///     }
75/// }
76/// ```
77pub trait NodeId: Copy + Eq + Hash + Debug + Send + Sync + 'static {
78    /// Construct a node identifier from a raw index.
79    fn from_raw(raw: usize) -> Self;
80    /// Convert the identifier back into its raw index.
81    fn to_raw(self) -> usize;
82}
83
84/// Marker trait implemented by symbol identifiers.
85pub trait SymbolId: Copy + Eq + Hash + Debug + Send + Sync + 'static {}
86
87/// Context object threaded through the parser.
88///
89/// This trait allows passing custom context data through the parsing process.
90/// Implement this trait for types that need to be accessible during parsing,
91/// such as symbol tables, error collectors, or configuration.
92///
93/// # When to Implement
94///
95/// Implement `GrammarContext` when you need to:
96/// - Track symbols during parsing
97/// - Collect errors or warnings
98/// - Pass configuration to parsing rules
99/// - Maintain state across rule evaluations
100///
101/// # Example
102///
103/// ```rust
104/// use sipha_core::traits::GrammarContext;
105///
106/// #[derive(Clone, Default, Debug)]
107/// struct MyContext {
108///     symbols: Vec<String>,
109///     errors: Vec<String>,
110/// }
111///
112/// impl GrammarContext for MyContext {}
113///
114/// // Use in parser
115/// let mut state = ParserState::new(&tokens, &mut arena, false, MyContext::default());
116/// ```
117pub trait GrammarContext: Clone + Default + Debug + Send + Sync + 'static {}
118
119impl GrammarContext for () {}
120
121impl<T> RuleId for T where T: Copy + Eq + Hash + Debug + Send + Sync + 'static {}
122
123impl<T> SymbolId for T where T: Copy + Eq + Hash + Debug + Send + Sync + 'static {}