markdown_ppp/ast_specialized/
element_id.rs

1//! Element ID support for AST nodes
2//!
3//! This module provides [`ElementId`] type for uniquely identifying AST elements
4//! and related functionality like ID generation.
5//!
6//! # Example
7//!
8//! ```rust
9//! use markdown_ppp::ast_specialized::element_id::{ElementId, IdGenerator};
10//!
11//! // Create element IDs
12//! let id1 = ElementId::new(42);
13//! let id2 = ElementId::from(100);
14//!
15//! // Generate sequential IDs
16//! let mut generator = IdGenerator::new();
17//! let id_a = generator.generate(); // ElementId(1)
18//! let id_b = generator.generate(); // ElementId(2)
19//!
20//! // Start from specific value
21//! let mut custom_gen = IdGenerator::starting_from(1000);
22//! let id_custom = custom_gen.generate(); // ElementId(1000)
23//! ```
24
25/// Unique identifier for an AST element
26#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
27#[cfg_attr(feature = "ast-serde", derive(serde::Serialize, serde::Deserialize))]
28pub struct ElementId(pub u64);
29
30impl ElementId {
31    /// Create a new element ID
32    pub fn new(id: u64) -> Self {
33        Self(id)
34    }
35
36    /// Get the raw ID value
37    pub fn id(&self) -> u64 {
38        self.0
39    }
40}
41
42impl From<u64> for ElementId {
43    fn from(id: u64) -> Self {
44        Self(id)
45    }
46}
47
48impl From<ElementId> for u64 {
49    fn from(element_id: ElementId) -> Self {
50        element_id.0
51    }
52}
53
54/// ID generator for creating unique element IDs
55#[derive(Debug, Clone)]
56pub struct IdGenerator {
57    next_id: u64,
58}
59
60impl IdGenerator {
61    /// Create a new ID generator starting from 1
62    pub fn new() -> Self {
63        Self { next_id: 1 }
64    }
65
66    /// Create a new ID generator starting from a specific value
67    pub fn starting_from(start_id: u64) -> Self {
68        Self { next_id: start_id }
69    }
70
71    /// Generate the next unique ID
72    pub fn generate(&mut self) -> ElementId {
73        let id = ElementId::new(self.next_id);
74        self.next_id += 1;
75        id
76    }
77
78    /// Peek at the next ID without consuming it
79    pub fn peek(&self) -> ElementId {
80        ElementId::new(self.next_id)
81    }
82
83    /// Reset the generator to start from 1 again
84    pub fn reset(&mut self) {
85        self.next_id = 1;
86    }
87}
88
89impl Default for IdGenerator {
90    fn default() -> Self {
91        Self::new()
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98
99    #[test]
100    fn test_element_id_basic() {
101        let id = ElementId::new(42);
102        assert_eq!(id.id(), 42);
103        assert_eq!(u64::from(id.clone()), 42);
104        assert_eq!(ElementId::from(42), id);
105    }
106
107    #[test]
108    fn test_id_generator() {
109        let mut gen = IdGenerator::new();
110        assert_eq!(gen.generate().id(), 1);
111        assert_eq!(gen.generate().id(), 2);
112        assert_eq!(gen.peek().id(), 3);
113        assert_eq!(gen.generate().id(), 3);
114
115        gen.reset();
116        assert_eq!(gen.generate().id(), 1);
117    }
118
119    #[test]
120    fn test_id_generator_starting_from() {
121        let mut gen = IdGenerator::starting_from(100);
122        assert_eq!(gen.generate().id(), 100);
123        assert_eq!(gen.generate().id(), 101);
124    }
125}