melodium_core/descriptor/
function.rs

1use core::fmt::{Display, Formatter, Result};
2use melodium_common::descriptor::{
3    Attribuable, Attributes, DataType, DescribedType, Documented, Function as FunctionDescriptor,
4    Generic, Generics, Identified, Identifier, OrderedParameterized, Parameter,
5};
6use melodium_common::executive::Value;
7use std::collections::HashMap;
8use std::sync::{Arc, Weak};
9
10#[derive(Debug)]
11pub struct Function {
12    identifier: Identifier,
13    #[cfg(feature = "doc")]
14    documentation: String,
15    attributes: Attributes,
16    generics: Vec<Generic>,
17    parameters: Vec<Parameter>,
18    return_type: DescribedType,
19    function: fn(HashMap<String, DataType>, Vec<Value>) -> Value,
20    auto_reference: Weak<Self>,
21}
22
23impl Function {
24    pub fn new(
25        identifier: Identifier,
26        documentation: String,
27        attributes: Attributes,
28        generics: Vec<Generic>,
29        parameters: Vec<Parameter>,
30        return_type: DescribedType,
31        function: fn(HashMap<String, DataType>, Vec<Value>) -> Value,
32    ) -> Arc<Self> {
33        #[cfg(not(feature = "doc"))]
34        let _ = documentation;
35        Arc::new_cyclic(|me| Self {
36            identifier,
37            #[cfg(feature = "doc")]
38            documentation,
39            attributes,
40            generics,
41            parameters,
42            return_type,
43            function,
44            auto_reference: me.clone(),
45        })
46    }
47}
48
49impl Attribuable for Function {
50    fn attributes(&self) -> &Attributes {
51        &self.attributes
52    }
53}
54
55impl FunctionDescriptor for Function {
56    fn return_type(&self) -> &DescribedType {
57        &self.return_type
58    }
59
60    fn function(&self) -> fn(HashMap<String, DataType>, Vec<Value>) -> Value {
61        self.function
62    }
63
64    fn as_identified(&self) -> Arc<dyn Identified> {
65        self.auto_reference.upgrade().unwrap()
66    }
67
68    fn as_ordered_parameterized(&self) -> Arc<dyn OrderedParameterized> {
69        self.auto_reference.upgrade().unwrap()
70    }
71}
72
73impl Identified for Function {
74    fn identifier(&self) -> &Identifier {
75        &self.identifier
76    }
77
78    fn make_use(&self, identifier: &Identifier) -> bool {
79        self.return_type
80            .final_type()
81            .data()
82            .map(|data| data.identifier() == identifier || data.make_use(identifier))
83            .unwrap_or(false)
84            || self.parameters.iter().any(|param| {
85                param
86                    .described_type()
87                    .final_type()
88                    .data()
89                    .map(|data| data.identifier() == identifier || data.make_use(identifier))
90                    .unwrap_or(false)
91            })
92    }
93
94    fn uses(&self) -> Vec<Identifier> {
95        let mut uses = Vec::new();
96        if let Some(data) = self.return_type.final_type().data() {
97            uses.push(data.identifier().clone());
98            uses.extend(data.uses());
99        }
100        for param in &self.parameters {
101            if let Some(data) = param.described_type().final_type().data() {
102                uses.push(data.identifier().clone());
103                uses.extend(data.uses());
104            }
105        }
106        uses
107    }
108}
109
110impl Documented for Function {
111    fn documentation(&self) -> &str {
112        #[cfg(feature = "doc")]
113        {
114            &self.documentation
115        }
116        #[cfg(not(feature = "doc"))]
117        {
118            &""
119        }
120    }
121}
122
123impl OrderedParameterized for Function {
124    fn parameters(&self) -> &Vec<Parameter> {
125        &self.parameters
126    }
127
128    fn as_identified(&self) -> Arc<dyn Identified> {
129        self.auto_reference.upgrade().unwrap()
130    }
131}
132
133impl Generics for Function {
134    fn generics(&self) -> &Vec<Generic> {
135        &self.generics
136    }
137}
138
139impl Display for Function {
140    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
141        write!(
142            f,
143            "function {}({})",
144            self.identifier.to_string(),
145            self.parameters()
146                .iter()
147                .map(|p| p.to_string())
148                .collect::<Vec<_>>()
149                .join(", "),
150        )?;
151
152        Ok(())
153    }
154}