syntax_parser_generator/handles/specials/automatically_handled.rs
1use crate::handles::{Handle, HandleCore, Handled};
2
3/// A data type for which handles can be automatically generated to identify its instances.
4///
5/// To do so, we need to implement the [AutomaticallyHandled::serial] method, that generates a
6/// unique serial-number with each instance of the type. This serial will be used to construct the
7/// identifying handle of the instance.
8///
9/// This usually serves for generating handles to instances of very simple data types, most commonly
10/// `enum`s. Such data types can be so easily enumerated, that there's no need to manage an
11/// auxiliary collection (e.g. [HandledVec](crate::handles::collections::HandledVec),
12/// [HandledHashMap](crate::handles::collections::HandledHashMap)) to associate enumerated handles
13/// with their known instances.
14///
15/// # Example
16/// ```rust
17/// # use syntax_parser_generator::handles::specials::AutomaticallyHandled;
18/// # #[derive(Clone, Copy)]
19/// enum MyLexemeType { Identifier, IntegerLiteral, If, While }
20/// impl AutomaticallyHandled for MyLexemeType {
21/// type HandleCoreType = u8;
22/// fn serial(&self) -> usize { *self as usize }
23/// }
24/// let identifier_lexeme_type = MyLexemeType::Identifier.handle();
25/// ```
26pub trait AutomaticallyHandled: Sized {
27 /// The internal representation of this type's handles (see [HandleCore] for more detail).
28 type HandleCoreType: HandleCore;
29
30 /// Generate a serial-number that identifies this instance of the type.
31 fn serial(&self) -> usize;
32
33 /// Get a handle to this instance of the type.
34 fn handle(&self) -> Handle<Self> {
35 self.serial().into()
36 }
37}
38
39impl<T> Handled for T
40where
41 T: AutomaticallyHandled,
42{
43 type HandleCoreType = T::HandleCoreType;
44}