Skip to main content

cobble/
stdlib.rs

1use std::collections::HashMap;
2
3/// Standard library module for Cobble
4/// Provides runtime support for event handling and built-in functions
5pub struct StdLib {
6    event_handlers: HashMap<EventType, Vec<String>>,
7}
8
9#[derive(Debug, Clone, Hash, PartialEq, Eq)]
10pub enum EventType {
11    Load, // When datapack is loaded (reset)
12    Tick, // Every game tick
13    Custom(String),
14}
15
16impl Default for StdLib {
17    fn default() -> Self {
18        Self::new()
19    }
20}
21
22impl StdLib {
23    pub fn new() -> Self {
24        Self {
25            event_handlers: HashMap::new(),
26        }
27    }
28
29    /// Register an event handler function
30    pub fn add_event_listener(&mut self, event_type: EventType, function_name: String) {
31        self.event_handlers
32            .entry(event_type)
33            .or_default()
34            .push(function_name);
35    }
36
37    /// Get all handlers for a specific event
38    pub fn get_event_handlers(&self, event_type: &EventType) -> Vec<String> {
39        self.event_handlers
40            .get(event_type)
41            .cloned()
42            .unwrap_or_default()
43    }
44
45    /// Generate the minecraft function tags for load and tick events
46    pub fn generate_tags(&self, namespace: &str) -> HashMap<String, Vec<String>> {
47        let mut tags = HashMap::new();
48
49        // Load tag (minecraft:load)
50        if let Some(handlers) = self.event_handlers.get(&EventType::Load) {
51            let load_functions: Vec<String> = handlers
52                .iter()
53                .map(|f| format!("{}:{}", namespace, f))
54                .collect();
55            tags.insert("minecraft:load".to_string(), load_functions);
56        }
57
58        // Tick tag (minecraft:tick)
59        if let Some(handlers) = self.event_handlers.get(&EventType::Tick) {
60            let tick_functions: Vec<String> = handlers
61                .iter()
62                .map(|f| format!("{}:{}", namespace, f))
63                .collect();
64            tags.insert("minecraft:tick".to_string(), tick_functions);
65        }
66
67        tags
68    }
69}
70
71/// Built-in functions that can be called from Cobble scripts
72pub mod builtins {
73    use crate::ast::Expression;
74
75    /// range(n) - Returns a list from 0 to n-1
76    pub fn range(n: i32) -> Vec<Expression> {
77        (0..n).map(|i| Expression::Number(i as f64)).collect()
78    }
79
80    /// len(list) - Returns the length of a list
81    pub fn len(list: &[Expression]) -> Expression {
82        Expression::Number(list.len() as f64)
83    }
84
85    /// str(value) - Converts a value to string
86    pub fn to_str(value: &Expression) -> Expression {
87        match value {
88            Expression::Number(n) => Expression::String(n.to_string()),
89            Expression::Boolean(b) => Expression::String(b.to_string()),
90            Expression::String(s) => Expression::String(s.clone()),
91            _ => Expression::String("None".to_string()),
92        }
93    }
94
95    /// int(value) - Converts a value to integer
96    pub fn to_int(value: &Expression) -> Expression {
97        match value {
98            Expression::Number(n) => Expression::Number(n.floor()),
99            Expression::String(s) => {
100                if let Ok(n) = s.parse::<f64>() {
101                    Expression::Number(n.floor())
102                } else {
103                    Expression::Number(0.0)
104                }
105            }
106            Expression::Boolean(b) => Expression::Number(if *b { 1.0 } else { 0.0 }),
107            _ => Expression::Number(0.0),
108        }
109    }
110}