plotnik_bytecode/type_system/
kind.rs

1//! Canonical type kind definitions.
2//!
3//! This enum represents the semantic type kinds shared across the system.
4//! Different modules may have their own representations that map to/from this.
5
6/// Semantic type kinds.
7///
8/// This is the canonical enumeration of all type kinds, including primitives.
9/// Primitive types (Void, Node, String) are stored as TypeDefs like any other type.
10#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
11#[repr(u8)]
12pub enum TypeKind {
13    /// Unit type - used for definitions with no captures.
14    Void = 0,
15    /// AST node reference.
16    Node = 1,
17    /// Text content extracted from node.
18    String = 2,
19    /// `T?` - optional wrapper, contains zero or one value.
20    Optional = 3,
21    /// `T*` - array of zero or more values.
22    ArrayZeroOrMore = 4,
23    /// `T+` - array of one or more values (non-empty).
24    ArrayOneOrMore = 5,
25    /// Record with named fields.
26    Struct = 6,
27    /// Discriminated union with tagged variants.
28    Enum = 7,
29    /// Named reference to another type (e.g., `type Foo = Bar`).
30    Alias = 8,
31}
32
33impl TypeKind {
34    /// Convert from raw discriminant.
35    pub fn from_u8(v: u8) -> Option<Self> {
36        match v {
37            0 => Some(Self::Void),
38            1 => Some(Self::Node),
39            2 => Some(Self::String),
40            3 => Some(Self::Optional),
41            4 => Some(Self::ArrayZeroOrMore),
42            5 => Some(Self::ArrayOneOrMore),
43            6 => Some(Self::Struct),
44            7 => Some(Self::Enum),
45            8 => Some(Self::Alias),
46            _ => None,
47        }
48    }
49
50    /// Whether this is a primitive/builtin type (Void, Node, String).
51    pub fn is_primitive(self) -> bool {
52        matches!(self, Self::Void | Self::Node | Self::String)
53    }
54
55    /// Whether this is a wrapper type (Optional, ArrayZeroOrMore, ArrayOneOrMore).
56    ///
57    /// Wrapper types contain a single inner type.
58    /// Composite types (Struct, Enum) have named members.
59    pub fn is_wrapper(self) -> bool {
60        matches!(
61            self,
62            Self::Optional | Self::ArrayZeroOrMore | Self::ArrayOneOrMore
63        )
64    }
65
66    /// Whether this is a composite type (Struct, Enum).
67    pub fn is_composite(self) -> bool {
68        matches!(self, Self::Struct | Self::Enum)
69    }
70
71    /// Whether this is an array type.
72    pub fn is_array(self) -> bool {
73        matches!(self, Self::ArrayZeroOrMore | Self::ArrayOneOrMore)
74    }
75
76    /// For array types, whether the array is non-empty.
77    pub fn array_is_non_empty(self) -> bool {
78        matches!(self, Self::ArrayOneOrMore)
79    }
80
81    /// Whether this is an alias type.
82    pub fn is_alias(self) -> bool {
83        matches!(self, Self::Alias)
84    }
85
86    /// Get the display name for primitive types.
87    pub fn primitive_name(self) -> Option<&'static str> {
88        match self {
89            Self::Void => Some("Void"),
90            Self::Node => Some("Node"),
91            Self::String => Some("String"),
92            _ => None,
93        }
94    }
95}