1use crate::Package;
2use lealang_chalk_rs::Chalk;
3use std::{collections::HashMap, sync::Arc};
4
5use super::{set_into_extends, ExtendsInternal, HeapWrapper, Options};
6
7pub type Args = *const [&'static str];
9pub type PackageCallback = fn(Args, HeapWrapper, &str, &mut Options) -> ();
10
11pub type MethodRes = &'static [(&'static str, PackageCallback)];
12
13pub struct LanguagePackages<'a> {
14 pub inner: HashMap<&'static str, (&'a str, PackageCallback)>,
15 pub(crate) extends: Arc<ExtendsInternal>,
16}
17
18impl<'a> LanguagePackages<'a> {
19 pub fn new() -> Self {
20 Self {
21 inner: HashMap::new(),
22 extends: Arc::new(ExtendsInternal::default()),
23 }
24 }
25
26 pub fn import_dyn(&mut self, func: Box<dyn Package>) -> &mut Self {
27 let name = String::from_utf8_lossy(func.name());
28 let name: &'static mut str = name.to_string().leak::<'static>();
29 for (key, val) in func.methods() {
30 self.inner.insert(key, (name, *val));
31 }
32
33 let ext = unsafe { Arc::get_mut_unchecked(&mut self.extends) };
35
36 set_into_extends(func.prototype(), ext);
37
38 self
39 }
40
41 pub fn import_static(&mut self, func: &'static dyn Package) -> &mut Self {
42 let name = String::from_utf8_lossy(func.name());
43 let name: &'static mut str = name.to_string().leak::<'static>();
44 for (key, val) in func.methods() {
45 self.inner.insert(key, (name, *val));
46 }
47
48 let ext = unsafe { Arc::get_mut_unchecked(&mut self.extends) };
50
51 set_into_extends(func.prototype(), ext);
52
53 self
54 }
55
56 pub fn import<T: Package + 'static>(&mut self, func: T) -> &mut Self {
57 self.import_dyn(Box::new(func))
58 }
59
60 pub fn list(&self, chalk: &mut Chalk) {
61 println!(
62 "{} {}",
63 chalk.reset_weight().blue().string(&"Total Commands:"),
64 self.inner.len()
65 );
66 chalk.reset_weight().green().println(&"Commands:");
67
68 self
69 .inner
70 .iter()
71 .enumerate()
72 .for_each(|(no, (syntax, (name, _)))| {
73 chalk.red().print(&format!("{}- ", no + 1));
74 chalk.yellow().bold().print(&syntax);
75 print!(" from ");
76 chalk.reset_weight().blue().println(&name);
77 });
78 }
79}