Skip to main content

mailang_stdlib/stdlib/
mod.rs

1//! MaìLang standard library
2//!
3//! This module provides built-in functions for MaìLang.
4
5mod convert;
6mod io;
7mod json;
8mod math;
9mod string;
10mod sys;
11mod time;
12
13pub use convert::*;
14pub use io::*;
15pub use json::*;
16pub use math::*;
17pub use string::*;
18pub use sys::*;
19pub use time::*;
20
21use mailang_bytecode::Value;
22
23// Output capture for WASM builds
24#[cfg(feature = "capture-output")]
25mod capture {
26    use std::sync::Mutex;
27
28    lazy_static::lazy_static! {
29        static ref CAPTURED_OUTPUT: Mutex<Vec<String>> = Mutex::new(Vec::new());
30        static ref IS_CAPTURED: Mutex<bool> = Mutex::new(false);
31    }
32
33    pub fn set_captured(captured: bool) -> bool {
34        let mut is_captured = IS_CAPTURED.lock().unwrap();
35        let prev = *is_captured;
36        *is_captured = captured;
37        if captured {
38            CAPTURED_OUTPUT.lock().unwrap().clear();
39        }
40        prev
41    }
42
43    pub fn get_output() -> Vec<String> {
44        CAPTURED_OUTPUT.lock().unwrap().clone()
45    }
46
47    pub fn is_captured() -> bool {
48        *IS_CAPTURED.lock().unwrap()
49    }
50
51    pub fn push_line(line: String) {
52        CAPTURED_OUTPUT.lock().unwrap().push(line);
53    }
54
55    pub fn push_text(text: String) {
56        let mut output = CAPTURED_OUTPUT.lock().unwrap();
57        if let Some(last) = output.last_mut() {
58            last.push_str(&text);
59        } else {
60            output.push(text);
61        }
62    }
63}
64
65/// Enable or disable output capture mode (only available with capture-output feature).
66#[cfg(feature = "capture-output")]
67pub fn set_println_captured(captured: bool) -> bool {
68    capture::set_captured(captured)
69}
70
71/// Get the captured output lines (only available with capture-output feature).
72#[cfg(feature = "capture-output")]
73pub fn get_captured_output() -> Vec<String> {
74    capture::get_output()
75}
76
77pub fn value_to_string(v: &Value) -> String {
78    match v {
79        Value::Null => "null".to_string(),
80        Value::Bool(b) => b.to_string(),
81        Value::Int(n) => n.to_string(),
82        Value::Float(n) => n.to_string(),
83        Value::Str(s) => s.to_string(),
84        Value::Char(c) => c.to_string(),
85        Value::Array(arr) => {
86            let items: Vec<String> = arr.borrow().iter().map(value_to_string).collect();
87            format!("[{}]", items.join(", "))
88        }
89        Value::Map(m) => {
90            let items: Vec<String> = m
91                .borrow()
92                .iter()
93                .map(|(k, v)| format!("{}: {}", value_to_string(k), value_to_string(v)))
94                .collect();
95            format!("{{{}}}", items.join(", "))
96        }
97        Value::Tuple(t) => {
98            let items: Vec<String> = t.borrow().iter().map(value_to_string).collect();
99            format!("({})", items.join(", "))
100        }
101        Value::Function(f) => format!("<fn {}>", f.name),
102        Value::Closure(c) => format!("<closure {}>", c.function_index),
103        Value::Class(cls) => format!("<class {}>", cls.name),
104        Value::Instance { class_index, .. } => format!("<instance {}>", class_index),
105        Value::Ok(v) => format!("Ok({})", value_to_string(v)),
106        Value::Err(v) => format!("Err({})", value_to_string(v)),
107        Value::Some(v) => format!("Some({})", value_to_string(v)),
108        Value::Builtin { name, .. } => format!("<builtin {}>", name),
109    }
110}