sciforge_hub/engine/query/
mod.rs1#[cfg(feature = "cross_domain")]
8mod astrobiology;
9#[cfg(feature = "cross_domain")]
10mod astrochemistry;
11#[cfg(feature = "astronomy")]
12mod astronomy;
13#[cfg(feature = "cross_domain")]
14mod astrophysics;
15#[cfg(feature = "cross_domain")]
16mod atmospheric_chemistry;
17#[cfg(feature = "cross_domain")]
18mod atmospheric_physics;
19#[cfg(feature = "cross_domain")]
20mod biochemistry;
21#[cfg(feature = "biology")]
22mod biology;
23#[cfg(feature = "cross_domain")]
24mod biomathematics;
25#[cfg(feature = "cross_domain")]
26mod biophysics;
27#[cfg(feature = "chemistry")]
28mod chemistry;
29#[cfg(feature = "cross_domain")]
30mod geochemistry;
31#[cfg(feature = "geology")]
32mod geology;
33#[cfg(feature = "cross_domain")]
34mod geophysics;
35#[cfg(feature = "cross_domain")]
36mod mathematical_physics;
37#[cfg(feature = "maths")]
38mod maths;
39#[cfg(feature = "meteorology")]
40mod meteorology;
41#[cfg(feature = "physics")]
42mod physics;
43#[cfg(feature = "cross_domain")]
44mod planetary_geology;
45
46use crate::engine::experience::experiment::DomainType;
47
48#[derive(Debug, Clone)]
50pub struct FunctionInfo {
51 pub domain: DomainType,
53 pub name: String,
55 pub param_names: Vec<String>,
57 pub description: String,
59}
60
61pub struct Catalog {
63 entries: Vec<FunctionInfo>,
64}
65
66impl Catalog {
67 pub fn new() -> Self {
69 let chunks: Vec<Vec<FunctionInfo>> = vec![
70 #[cfg(feature = "astronomy")]
71 { let mut v = Vec::new(); astronomy::register(&mut v); v },
72 #[cfg(feature = "geology")]
73 { let mut v = Vec::new(); geology::register(&mut v); v },
74 #[cfg(feature = "meteorology")]
75 { let mut v = Vec::new(); meteorology::register(&mut v); v },
76 #[cfg(feature = "physics")]
77 { let mut v = Vec::new(); physics::register(&mut v); v },
78 #[cfg(feature = "chemistry")]
79 { let mut v = Vec::new(); chemistry::register(&mut v); v },
80 #[cfg(feature = "biology")]
81 { let mut v = Vec::new(); biology::register(&mut v); v },
82 #[cfg(feature = "maths")]
83 { let mut v = Vec::new(); maths::register(&mut v); v },
84 #[cfg(feature = "cross_domain")]
85 { let mut v = Vec::new(); astrochemistry::register(&mut v); v },
86 #[cfg(feature = "cross_domain")]
87 { let mut v = Vec::new(); geophysics::register(&mut v); v },
88 #[cfg(feature = "cross_domain")]
89 { let mut v = Vec::new(); astrophysics::register(&mut v); v },
90 #[cfg(feature = "cross_domain")]
91 { let mut v = Vec::new(); biochemistry::register(&mut v); v },
92 #[cfg(feature = "cross_domain")]
93 { let mut v = Vec::new(); biophysics::register(&mut v); v },
94 #[cfg(feature = "cross_domain")]
95 { let mut v = Vec::new(); geochemistry::register(&mut v); v },
96 #[cfg(feature = "cross_domain")]
97 { let mut v = Vec::new(); astrobiology::register(&mut v); v },
98 #[cfg(feature = "cross_domain")]
99 { let mut v = Vec::new(); atmospheric_chemistry::register(&mut v); v },
100 #[cfg(feature = "cross_domain")]
101 { let mut v = Vec::new(); atmospheric_physics::register(&mut v); v },
102 #[cfg(feature = "cross_domain")]
103 { let mut v = Vec::new(); planetary_geology::register(&mut v); v },
104 #[cfg(feature = "cross_domain")]
105 { let mut v = Vec::new(); biomathematics::register(&mut v); v },
106 #[cfg(feature = "cross_domain")]
107 { let mut v = Vec::new(); mathematical_physics::register(&mut v); v },
108 ];
109 let entries: Vec<FunctionInfo> = chunks.into_iter().flatten().collect();
110 Self { entries }
111 }
112
113 pub fn len(&self) -> usize {
115 self.entries.len()
116 }
117 pub fn is_empty(&self) -> bool {
119 self.entries.is_empty()
120 }
121
122 pub fn by_domain(&self, domain: &DomainType) -> Vec<&FunctionInfo> {
124 let d = format!("{:?}", domain);
125 self.entries
126 .iter()
127 .filter(|e| format!("{:?}", e.domain) == d)
128 .collect()
129 }
130
131 pub fn search(&self, pattern: &str) -> Vec<&FunctionInfo> {
133 let p = pattern.to_lowercase();
134 self.entries
135 .iter()
136 .filter(|e| e.name.to_lowercase().contains(&p))
137 .collect()
138 }
139
140 pub fn get(&self, name: &str) -> Option<&FunctionInfo> {
142 self.entries.iter().find(|e| e.name == name)
143 }
144
145 pub fn names(&self) -> Vec<&str> {
147 self.entries.iter().map(|e| e.name.as_str()).collect()
148 }
149
150 pub fn domain_summary(&self) -> Vec<(String, usize)> {
152 let domains = [
153 "Maths",
154 "Physics",
155 "Chemistry",
156 "Biology",
157 "Astronomy",
158 "Geology",
159 "Meteorology",
160 "Astrochemistry",
161 "Geophysics",
162 "Astrophysics",
163 "Biochemistry",
164 "Biophysics",
165 "Geochemistry",
166 "Astrobiology",
167 "AtmosphericChemistry",
168 "AtmosphericPhysics",
169 "PlanetaryGeology",
170 "Biomathematics",
171 "MathematicalPhysics",
172 ];
173 domains
174 .iter()
175 .map(|&d| {
176 let count = self
177 .entries
178 .iter()
179 .filter(|e| format!("{:?}", e.domain) == d)
180 .count();
181 (d.to_string(), count)
182 })
183 .collect()
184 }
185
186 pub fn by_param(&self, param: &str) -> Vec<&FunctionInfo> {
188 self.entries
189 .iter()
190 .filter(|e| e.param_names.iter().any(|p| p == param))
191 .collect()
192 }
193
194 pub fn by_param_count(&self, n: usize) -> Vec<&FunctionInfo> {
196 self.entries
197 .iter()
198 .filter(|e| e.param_names.len() == n)
199 .collect()
200 }
201
202 pub fn to_markdown(&self) -> String {
204 let mut out = String::from("# SciForge Function Catalog\n\n");
205 let summary = self.domain_summary();
206 let total: usize = summary.iter().map(|(_, c)| c).sum();
207 out.push_str(&format!("**Total functions: {}**\n\n", total));
208 out.push_str("| Domain | Functions |\n|--------|----------|\n");
209 for (d, c) in &summary {
210 out.push_str(&format!("| {} | {} |\n", d, c));
211 }
212 out
213 }
214}
215
216impl Default for Catalog {
217 fn default() -> Self {
218 Self::new()
219 }
220}
221
222#[cfg(any(
223 feature = "astronomy",
224 feature = "biology",
225 feature = "chemistry",
226 feature = "geology",
227 feature = "maths",
228 feature = "meteorology",
229 feature = "physics",
230 feature = "cross_domain",
231))]
232pub(super) fn reg(
233 entries: &mut Vec<FunctionInfo>,
234 domain: DomainType,
235 name: &str,
236 params: &[&str],
237 desc: &str,
238) {
239 entries.push(FunctionInfo {
240 domain,
241 name: name.into(),
242 param_names: params.iter().map(|s| s.to_string()).collect(),
243 description: desc.into(),
244 });
245}