cainome_parser/tokens/
basic.rs

1//! Core basic types are built-in types that are available in the core library
2//! and which are not a struct nor an enum, nor an array.
3//!
4//! This module provides a parser for core basic types.
5use super::constants::{CAIRO_CORE_BASIC, UNIT_TYPE};
6use crate::{CainomeResult, Error};
7
8#[derive(Debug, Clone, PartialEq)]
9pub struct CoreBasic {
10    pub type_path: String,
11}
12
13impl CoreBasic {
14    /// Parses a core basic type from a type path.
15    ///
16    /// # Arguments
17    ///
18    /// * `type_path` - The type path to parse.
19    ///
20    /// # Returns
21    ///
22    /// Returns a [`CoreBasic`] token if the type path is a core basic type.
23    /// Returns an error otherwise.
24    pub fn parse(type_path: &str) -> CainomeResult<Self> {
25        // Unit type is for now included in basic type.
26        if type_path == UNIT_TYPE {
27            return Ok(Self {
28                type_path: type_path.to_string(),
29            });
30        }
31
32        if !CAIRO_CORE_BASIC.contains(&type_path) {
33            return Err(Error::TokenInitFailed(format!(
34                "CoreBasic token couldn't be initialized from `{}`",
35                type_path,
36            )));
37        }
38
39        Ok(Self {
40            type_path: type_path.to_string(),
41        })
42    }
43
44    /// Returns the name of the core basic type.
45    ///
46    /// The type name is the last part of the type path, to remove any
47    /// module name.
48    /// The type name is also removing any generic parameters, if any.
49    ///
50    /// # Example
51    ///
52    /// ```rust
53    /// use cainome_parser::tokens::CoreBasic;
54    ///
55    /// let core_basic = CoreBasic::parse("core::felt252").unwrap();
56    /// assert_eq!(core_basic.type_name(), "felt252");
57    /// ```
58    ///
59    /// # Returns
60    ///
61    /// Returns the name of the core basic type.
62    pub fn type_name(&self) -> String {
63        let f = self
64            .type_path
65            .split('<')
66            .nth(0)
67            .unwrap_or(&self.type_path)
68            .trim_end_matches("::")
69            .to_string();
70
71        f.split("::").last().unwrap_or(&f).to_string()
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    #[test]
80    fn test_parse() {
81        assert_eq!(
82            CoreBasic::parse("core::felt252").unwrap(),
83            CoreBasic {
84                type_path: "core::felt252".to_string(),
85            }
86        );
87
88        assert_eq!(
89            CoreBasic::parse("core::integer::u64").unwrap(),
90            CoreBasic {
91                type_path: "core::integer::u64".to_string(),
92            }
93        );
94    }
95
96    #[test]
97    fn test_parse_unit() {
98        assert_eq!(
99            CoreBasic::parse("()").unwrap(),
100            CoreBasic {
101                type_path: "()".to_string(),
102            }
103        );
104    }
105
106    #[test]
107    fn test_parse_array_span_invalid() {
108        assert!(CoreBasic::parse("core::array::Array<core::felt252>").is_err());
109        assert!(CoreBasic::parse("core::array::Span<core::felt252>").is_err());
110    }
111
112    #[test]
113    fn test_parse_composite_invalid() {
114        assert!(CoreBasic::parse("mymodule::MyStruct").is_err());
115        assert!(CoreBasic::parse("module2::module3::MyStruct<core::felt252>").is_err());
116    }
117}