Skip to main content

ryo_symbol/
var_scope.rs

1//! Variable scope for InSymbol (variables, parameters, fields)
2
3use serde::{Deserialize, Serialize};
4
5/// Variable scope type for InSymbol
6///
7/// Used to distinguish different kinds of "inner" symbols within
8/// a containing symbol (function, struct, etc.).
9///
10/// # Path Format
11/// - Parameter: `my_crate::my_fn::$param::x`
12/// - Local variable: `my_crate::my_fn::$var::result`
13/// - Struct field: `my_crate::MyStruct::$field::name`
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
15pub enum VarScope {
16    /// Function parameter: `$param`
17    Param,
18    /// Local variable: `$var`
19    Local,
20    /// Struct/enum field: `$field`
21    Field,
22}
23
24impl VarScope {
25    /// Get the scope segment string
26    ///
27    /// # Examples
28    /// ```
29    /// # use ryo_symbol::VarScope;
30    /// assert_eq!(VarScope::Param.segment(), "$param");
31    /// assert_eq!(VarScope::Local.segment(), "$var");
32    /// assert_eq!(VarScope::Field.segment(), "$field");
33    /// ```
34    pub fn segment(&self) -> &'static str {
35        match self {
36            VarScope::Param => "$param",
37            VarScope::Local => "$var",
38            VarScope::Field => "$field",
39        }
40    }
41
42    /// Parse from a segment string
43    ///
44    /// # Examples
45    /// ```
46    /// # use ryo_symbol::VarScope;
47    /// assert_eq!(VarScope::from_segment("$param"), Some(VarScope::Param));
48    /// assert_eq!(VarScope::from_segment("$var"), Some(VarScope::Local));
49    /// assert_eq!(VarScope::from_segment("$field"), Some(VarScope::Field));
50    /// assert_eq!(VarScope::from_segment("foo"), None);
51    /// ```
52    pub fn from_segment(s: &str) -> Option<Self> {
53        match s {
54            "$param" => Some(VarScope::Param),
55            "$var" => Some(VarScope::Local),
56            "$field" => Some(VarScope::Field),
57            _ => None,
58        }
59    }
60
61    /// Check if a string is a valid scope marker
62    pub fn is_scope_marker(s: &str) -> bool {
63        Self::from_segment(s).is_some()
64    }
65}
66
67impl std::fmt::Display for VarScope {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        write!(f, "{}", self.segment())
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn test_var_scope_segment() {
79        assert_eq!(VarScope::Param.segment(), "$param");
80        assert_eq!(VarScope::Local.segment(), "$var");
81        assert_eq!(VarScope::Field.segment(), "$field");
82    }
83
84    #[test]
85    fn test_var_scope_from_segment() {
86        assert_eq!(VarScope::from_segment("$param"), Some(VarScope::Param));
87        assert_eq!(VarScope::from_segment("$var"), Some(VarScope::Local));
88        assert_eq!(VarScope::from_segment("$field"), Some(VarScope::Field));
89        assert_eq!(VarScope::from_segment("invalid"), None);
90        assert_eq!(VarScope::from_segment("$invalid"), None);
91    }
92
93    #[test]
94    fn test_var_scope_display() {
95        assert_eq!(format!("{}", VarScope::Param), "$param");
96        assert_eq!(format!("{}", VarScope::Local), "$var");
97        assert_eq!(format!("{}", VarScope::Field), "$field");
98    }
99}