Skip to main content

ryo_source/pure/
item.rs

1//! ItemKind - Shared vocabulary for AST item types.
2//!
3//! This is the canonical definition of item kinds used across the ryo ecosystem.
4//! All crates should use this definition instead of creating their own.
5
6/// Kind of AST item (shared vocabulary across crates).
7///
8/// This enum represents the type of an AST item and is used for:
9/// - Item-level conflict detection in parallel execution
10/// - Intent extraction and pattern matching
11/// - Spec directives and documentation
12///
13/// # Design
14///
15/// - Top-level items: items that can appear at module level
16/// - Nested items: items that appear inside other items (methods in impl, fields in struct)
17/// - Wildcard: for pattern matching any kind
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
21pub enum ItemKind {
22    // ========== Top-level items ==========
23    /// Function definition (`fn foo() {}`)
24    Function,
25    /// Struct definition (`struct Foo {}`)
26    Struct,
27    /// Enum definition (`enum Foo {}`)
28    Enum,
29    /// Trait definition (`trait Foo {}`)
30    Trait,
31    /// Impl block (`impl Foo {}` or `impl Trait for Foo {}`)
32    Impl,
33    /// Type alias (`type Foo = Bar;`)
34    TypeAlias,
35    /// Const item (`const FOO: i32 = 1;`)
36    Const,
37    /// Static item (`static FOO: i32 = 1;`)
38    Static,
39    /// Module (`mod foo;` or `mod foo {}`)
40    Mod,
41    /// Use statement (`use std::io;`)
42    Use,
43    /// Macro invocation at item level (`macro_rules!` or `foo!()`)
44    Macro,
45
46    // ========== Nested items ==========
47    /// Method inside an impl or trait block
48    Method,
49    /// Field in a struct or enum variant
50    Field,
51    /// Variant in an enum
52    Variant,
53
54    // ========== Variable-level items ==========
55    /// Local variable (`let x = ...`)
56    LocalVar,
57    /// Function parameter
58    Parameter,
59    /// Tuple struct/enum field (indexed by number: 0, 1, 2...)
60    TupleField,
61
62    // ========== Special ==========
63    /// Wildcard - matches any kind (for pattern matching)
64    Any,
65    /// Unknown or unsupported item
66    Other,
67}
68
69impl ItemKind {
70    /// Returns the string representation of this kind.
71    pub fn as_str(&self) -> &'static str {
72        match self {
73            ItemKind::Function => "fn",
74            ItemKind::Struct => "struct",
75            ItemKind::Enum => "enum",
76            ItemKind::Trait => "trait",
77            ItemKind::Impl => "impl",
78            ItemKind::TypeAlias => "type",
79            ItemKind::Const => "const",
80            ItemKind::Static => "static",
81            ItemKind::Mod => "mod",
82            ItemKind::Use => "use",
83            ItemKind::Macro => "macro",
84            ItemKind::Method => "method",
85            ItemKind::Field => "field",
86            ItemKind::Variant => "variant",
87            ItemKind::LocalVar => "var",
88            ItemKind::Parameter => "param",
89            ItemKind::TupleField => "tuple_field",
90            ItemKind::Any => "*",
91            ItemKind::Other => "other",
92        }
93    }
94
95    /// Returns true if this is a top-level item (can appear at module level).
96    pub fn is_top_level(&self) -> bool {
97        matches!(
98            self,
99            ItemKind::Function
100                | ItemKind::Struct
101                | ItemKind::Enum
102                | ItemKind::Trait
103                | ItemKind::Impl
104                | ItemKind::TypeAlias
105                | ItemKind::Const
106                | ItemKind::Static
107                | ItemKind::Mod
108                | ItemKind::Use
109                | ItemKind::Macro
110        )
111    }
112
113    /// Returns true if this is a nested item (appears inside another item).
114    pub fn is_nested(&self) -> bool {
115        matches!(
116            self,
117            ItemKind::Method | ItemKind::Field | ItemKind::Variant | ItemKind::TupleField
118        )
119    }
120
121    /// Returns true if this is a variable-level item (local scope).
122    pub fn is_variable(&self) -> bool {
123        matches!(self, ItemKind::LocalVar | ItemKind::Parameter)
124    }
125
126    /// Returns true if this matches the given kind (considering Any as wildcard).
127    pub fn matches(&self, other: &ItemKind) -> bool {
128        *self == ItemKind::Any || *other == ItemKind::Any || self == other
129    }
130}
131
132impl std::fmt::Display for ItemKind {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        write!(f, "{}", self.as_str())
135    }
136}
137
138impl From<&super::PureItem> for ItemKind {
139    fn from(item: &super::PureItem) -> Self {
140        match item {
141            super::PureItem::Use(_) => ItemKind::Use,
142            super::PureItem::Fn(_) => ItemKind::Function,
143            super::PureItem::Struct(_) => ItemKind::Struct,
144            super::PureItem::Enum(_) => ItemKind::Enum,
145            super::PureItem::Impl(_) => ItemKind::Impl,
146            super::PureItem::Const(_) => ItemKind::Const,
147            super::PureItem::Static(_) => ItemKind::Static,
148            super::PureItem::Type(_) => ItemKind::TypeAlias,
149            super::PureItem::Mod(_) => ItemKind::Mod,
150            super::PureItem::Trait(_) => ItemKind::Trait,
151            super::PureItem::Macro(_) => ItemKind::Macro,
152            super::PureItem::Other(_) => ItemKind::Other,
153        }
154    }
155}
156
157impl From<super::PureSymbolKind> for ItemKind {
158    fn from(kind: super::PureSymbolKind) -> Self {
159        match kind {
160            super::PureSymbolKind::Function => ItemKind::Function,
161            super::PureSymbolKind::Struct => ItemKind::Struct,
162            super::PureSymbolKind::Enum => ItemKind::Enum,
163            super::PureSymbolKind::Trait => ItemKind::Trait,
164            super::PureSymbolKind::TypeAlias => ItemKind::TypeAlias,
165            super::PureSymbolKind::Const => ItemKind::Const,
166            super::PureSymbolKind::Static => ItemKind::Static,
167            super::PureSymbolKind::Module => ItemKind::Mod,
168            super::PureSymbolKind::Impl => ItemKind::Impl,
169            super::PureSymbolKind::LocalVar => ItemKind::LocalVar,
170            super::PureSymbolKind::Parameter => ItemKind::Parameter,
171        }
172    }
173}
174
175#[cfg(test)]
176mod tests {
177    use super::*;
178
179    #[test]
180    fn test_as_str() {
181        assert_eq!(ItemKind::Function.as_str(), "fn");
182        assert_eq!(ItemKind::Struct.as_str(), "struct");
183        assert_eq!(ItemKind::Method.as_str(), "method");
184    }
185
186    #[test]
187    fn test_is_top_level() {
188        assert!(ItemKind::Function.is_top_level());
189        assert!(ItemKind::Struct.is_top_level());
190        assert!(!ItemKind::Method.is_top_level());
191        assert!(!ItemKind::Field.is_top_level());
192    }
193
194    #[test]
195    fn test_is_nested() {
196        assert!(!ItemKind::Function.is_nested());
197        assert!(ItemKind::Method.is_nested());
198        assert!(ItemKind::Field.is_nested());
199        assert!(ItemKind::Variant.is_nested());
200        assert!(ItemKind::TupleField.is_nested());
201    }
202
203    #[test]
204    fn test_is_variable() {
205        assert!(ItemKind::LocalVar.is_variable());
206        assert!(ItemKind::Parameter.is_variable());
207        assert!(!ItemKind::Function.is_variable());
208        assert!(!ItemKind::Field.is_variable());
209    }
210
211    #[test]
212    fn test_matches_wildcard() {
213        assert!(ItemKind::Any.matches(&ItemKind::Function));
214        assert!(ItemKind::Function.matches(&ItemKind::Any));
215        assert!(ItemKind::Function.matches(&ItemKind::Function));
216        assert!(!ItemKind::Function.matches(&ItemKind::Struct));
217    }
218
219    #[test]
220    fn test_display() {
221        assert_eq!(format!("{}", ItemKind::Function), "fn");
222        assert_eq!(format!("{}", ItemKind::Struct), "struct");
223    }
224}