melodium_core/descriptor/
function.rs1use 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}