use std::{borrow::Cow, collections::HashMap}; use oyster_builtin_proc::builtin; use crate::Shell; #[derive(Clone, Copy)] pub struct Builtin { pub name: &'static str, pub description: &'static str, pub fun: fn(shell: &mut Shell, args: &[Cow]), } #[builtin(description = "prints help for different builtins")] fn help(shell: &mut Shell, _args: &[Cow]) { println!( r"oyster help: These are the loaded builtins:" ); for builtin in shell.builtins().iter() { println!(" {: <8} {}", builtin.name, builtin.description); } } /// Used to register and retrieve builtins. #[derive(Default)] pub struct BuiltinMap(HashMap<&'static str, Builtin>); impl BuiltinMap { /// Register a new builtin. pub fn add(&mut self, builtin: Builtin) { self.0.insert(builtin.name, builtin); } /// Get a builtin with a given name, if it exists. pub fn get(&self, name: &str) -> Option<&Builtin> { self.0.get(name) } /// Returns an iterator over all currently registered builtins. pub fn iter(&self) -> impl Iterator { self.0.iter().map(|(_, v)| v) } /// Add default builtins. pub fn add_defaults(&mut self) { self.add(help); } } impl Shell { /// Retrieve builtins. pub fn builtins(&self) -> &BuiltinMap { &self.builtins } /// Retrieve builtins, mutably. pub fn builtins_mut(&mut self) -> &mut BuiltinMap { &mut self.builtins } }