Skip to main content

shrub_core/
functions.rs

1//! Structures for managing function registrations and calls.
2
3use std::collections::HashMap;
4use std::sync::Arc;
5
6/// An environment for defined, named functions.
7#[derive(Clone, Default)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct FunctionEnv {
10    functions: HashMap<String, Registration>,
11}
12
13impl FunctionEnv {
14    /// Tries to retrieve the registration for a function by name.
15    ///
16    /// # Arguments
17    ///
18    /// * `name` - The name of the function to retrieve.
19    pub fn get(&self, name: &str) -> Option<&Registration> {
20        self.functions.get(name)
21    }
22
23    /// Tries to retrieve a mutable reference to the registration for a
24    /// function by name.
25    ///
26    /// # Arguments
27    ///
28    /// * `name` - The name of the function to retrieve.
29    pub fn get_mut(&mut self, name: &str) -> Option<&mut Registration> {
30        self.functions.get_mut(name)
31    }
32
33    /// Unregisters a function from the environment.
34    ///
35    /// # Arguments
36    ///
37    /// * `name` - The name of the function to remove.
38    pub fn remove(&mut self, name: &str) -> Option<Registration> {
39        self.functions.remove(name)
40    }
41
42    /// Updates a function registration in this environment.
43    ///
44    /// # Arguments
45    ///
46    /// * `name` - The name of the function to update.
47    /// * `registration` - The new registration for the function.
48    pub fn update(&mut self, name: String, registration: Registration) {
49        self.functions.insert(name, registration);
50    }
51
52    /// Clear all functions in this environment.
53    pub fn clear(&mut self) {
54        self.functions.clear();
55    }
56
57    /// Returns an iterator over the functions registered in this environment.
58    pub fn iter(&self) -> impl Iterator<Item = (&String, &Registration)> {
59        self.functions.iter()
60    }
61}
62
63/// Encapsulates a registration for a defined function.
64#[derive(Clone, Debug)]
65#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
66pub struct Registration {
67    /// The parsed definition of the function.
68    definition: Arc<shrub_parser::ast::FunctionDefinition>,
69    /// The source info for the function definition.
70    source_info: crate::SourceInfo,
71    /// Whether or not this function definition should be exported to children.
72    exported: bool,
73}
74
75impl From<shrub_parser::ast::FunctionDefinition> for Registration {
76    fn from(definition: shrub_parser::ast::FunctionDefinition) -> Self {
77        Self {
78            definition: Arc::new(definition),
79            source_info: crate::SourceInfo::default(),
80            exported: false,
81        }
82    }
83}
84
85impl Registration {
86    /// Creates a new function registration.
87    ///
88    /// # Arguments
89    ///
90    /// * `definition` - The function definition.
91    /// * `source_info` - Source information for the function definition.
92    pub fn new(
93        definition: shrub_parser::ast::FunctionDefinition,
94        source_info: &crate::SourceInfo,
95    ) -> Self {
96        Self {
97            definition: Arc::new(definition),
98            source_info: source_info.clone(),
99            exported: false,
100        }
101    }
102
103    /// Returns a reference to the function definition.
104    pub fn definition(&self) -> &shrub_parser::ast::FunctionDefinition {
105        &self.definition
106    }
107
108    /// Returns a reference to the source info for the function definition.
109    pub const fn source(&self) -> &crate::SourceInfo {
110        &self.source_info
111    }
112
113    /// Marks the function for export.
114    pub const fn export(&mut self) {
115        self.exported = true;
116    }
117
118    /// Unmarks the function for export.
119    pub const fn unexport(&mut self) {
120        self.exported = false;
121    }
122
123    /// Returns whether this function is exported.
124    pub const fn is_exported(&self) -> bool {
125        self.exported
126    }
127}