Skip to main content

scarf_python/
define.rs

1// =======================================================================
2// define.rs
3// =======================================================================
4//! A wrapper around [`scarf_parser::preprocessor::Define`]
5
6use crate::{SpannedToken, lex};
7use pyo3::prelude::*;
8use scarf_parser::PreprocessorCache;
9
10/// A wrapper around [`scarf_parser::preprocessor::Define`]
11#[pyclass(eq, from_py_object, module = "scarf_python")]
12#[derive(Clone, PartialEq, Eq)]
13pub struct Define {
14    /// The name being defined
15    #[pyo3(get, set)]
16    pub name: String,
17    /// The replacement tokens, if any, to use
18    #[pyo3(get, set)]
19    pub body: Option<Vec<SpannedToken>>,
20}
21
22impl<'a> Define {
23    /// Turn a [`Define`] into a [`scarf_parser::preprocessor::Define`]
24    pub fn to_rust(
25        &'a self,
26        cache: &'a PreprocessorCache<'a>,
27    ) -> scarf_parser::preprocessor::Define<'a> {
28        scarf_parser::preprocessor::Define {
29            name: scarf_parser::SpannedString(
30                &self.name,
31                scarf_syntax::Span::default(),
32            ),
33            body: match &self.body {
34                Some(tokens) => scarf_parser::preprocessor::DefineBody::Text(
35                    tokens
36                        .into_iter()
37                        .map(|python_token| python_token.to_rust(cache))
38                        .collect(),
39                ),
40                None => scarf_parser::preprocessor::DefineBody::Empty,
41            },
42        }
43    }
44}
45
46/// Create a [`Define`] for a name with no replacement text
47#[pyfunction]
48pub fn define_empty(name: String) -> Define {
49    Define { name, body: None }
50}
51
52/// Create a [`Define`] for a name with some replacement text
53#[pyfunction]
54pub fn define_text(name: String, text: String) -> Define {
55    Define {
56        name,
57        body: Some(lex(text, "".to_string())),
58    }
59}