mod astrobiology;
mod astrochemistry;
mod astronomy;
mod astrophysics;
mod atmospheric_chemistry;
mod atmospheric_physics;
mod biochemistry;
mod biology;
mod biomathematics;
mod biophysics;
mod chemistry;
mod geochemistry;
mod geology;
mod geophysics;
mod mathematical_physics;
mod maths;
mod meteorology;
mod physics;
mod planetary_geology;
use crate::hub::engine::experience::experiment::DomainType;
#[derive(Debug, Clone)]
pub struct FunctionInfo {
pub domain: DomainType,
pub name: String,
pub param_names: Vec<String>,
pub description: String,
}
pub struct Catalog {
entries: Vec<FunctionInfo>,
}
impl Catalog {
pub fn new() -> Self {
let mut entries = Vec::new();
astronomy::register(&mut entries);
geology::register(&mut entries);
meteorology::register(&mut entries);
physics::register(&mut entries);
chemistry::register(&mut entries);
biology::register(&mut entries);
maths::register(&mut entries);
astrochemistry::register(&mut entries);
geophysics::register(&mut entries);
astrophysics::register(&mut entries);
biochemistry::register(&mut entries);
biophysics::register(&mut entries);
geochemistry::register(&mut entries);
astrobiology::register(&mut entries);
atmospheric_chemistry::register(&mut entries);
atmospheric_physics::register(&mut entries);
planetary_geology::register(&mut entries);
biomathematics::register(&mut entries);
mathematical_physics::register(&mut entries);
Self { entries }
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn by_domain(&self, domain: &DomainType) -> Vec<&FunctionInfo> {
let d = format!("{:?}", domain);
self.entries
.iter()
.filter(|e| format!("{:?}", e.domain) == d)
.collect()
}
pub fn search(&self, pattern: &str) -> Vec<&FunctionInfo> {
let p = pattern.to_lowercase();
self.entries
.iter()
.filter(|e| e.name.to_lowercase().contains(&p))
.collect()
}
pub fn get(&self, name: &str) -> Option<&FunctionInfo> {
self.entries.iter().find(|e| e.name == name)
}
pub fn names(&self) -> Vec<&str> {
self.entries.iter().map(|e| e.name.as_str()).collect()
}
pub fn domain_summary(&self) -> Vec<(String, usize)> {
let domains = [
"Maths",
"Physics",
"Chemistry",
"Biology",
"Astronomy",
"Geology",
"Meteorology",
"Astrochemistry",
"Geophysics",
"Astrophysics",
"Biochemistry",
"Biophysics",
"Geochemistry",
"Astrobiology",
"AtmosphericChemistry",
"AtmosphericPhysics",
"PlanetaryGeology",
"Biomathematics",
"MathematicalPhysics",
];
domains
.iter()
.map(|&d| {
let count = self
.entries
.iter()
.filter(|e| format!("{:?}", e.domain) == d)
.count();
(d.to_string(), count)
})
.collect()
}
pub fn by_param(&self, param: &str) -> Vec<&FunctionInfo> {
self.entries
.iter()
.filter(|e| e.param_names.iter().any(|p| p == param))
.collect()
}
pub fn by_param_count(&self, n: usize) -> Vec<&FunctionInfo> {
self.entries
.iter()
.filter(|e| e.param_names.len() == n)
.collect()
}
pub fn to_markdown(&self) -> String {
let mut out = String::from("# SciForge Function Catalog\n\n");
let summary = self.domain_summary();
let total: usize = summary.iter().map(|(_, c)| c).sum();
out.push_str(&format!("**Total functions: {}**\n\n", total));
out.push_str("| Domain | Functions |\n|--------|----------|\n");
for (d, c) in &summary {
out.push_str(&format!("| {} | {} |\n", d, c));
}
out
}
}
impl Default for Catalog {
fn default() -> Self {
Self::new()
}
}
pub(super) fn reg(
entries: &mut Vec<FunctionInfo>,
domain: DomainType,
name: &str,
params: &[&str],
desc: &str,
) {
entries.push(FunctionInfo {
domain,
name: name.into(),
param_names: params.iter().map(|s| s.to_string()).collect(),
description: desc.into(),
});
}