use std::collections::HashMap;
pub struct StdLib {
event_handlers: HashMap<EventType, Vec<String>>,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum EventType {
Load, Tick, Custom(String),
}
impl Default for StdLib {
fn default() -> Self {
Self::new()
}
}
impl StdLib {
pub fn new() -> Self {
Self {
event_handlers: HashMap::new(),
}
}
pub fn add_event_listener(&mut self, event_type: EventType, function_name: String) {
self.event_handlers
.entry(event_type)
.or_default()
.push(function_name);
}
pub fn get_event_handlers(&self, event_type: &EventType) -> Vec<String> {
self.event_handlers
.get(event_type)
.cloned()
.unwrap_or_default()
}
pub fn generate_tags(&self, namespace: &str) -> HashMap<String, Vec<String>> {
let mut tags = HashMap::new();
if let Some(handlers) = self.event_handlers.get(&EventType::Load) {
let load_functions: Vec<String> = handlers
.iter()
.map(|f| format!("{}:{}", namespace, f))
.collect();
tags.insert("minecraft:load".to_string(), load_functions);
}
if let Some(handlers) = self.event_handlers.get(&EventType::Tick) {
let tick_functions: Vec<String> = handlers
.iter()
.map(|f| format!("{}:{}", namespace, f))
.collect();
tags.insert("minecraft:tick".to_string(), tick_functions);
}
tags
}
}
pub mod builtins {
use crate::ast::Expression;
pub fn range(n: i32) -> Vec<Expression> {
(0..n).map(|i| Expression::Number(i as f64)).collect()
}
pub fn len(list: &[Expression]) -> Expression {
Expression::Number(list.len() as f64)
}
pub fn to_str(value: &Expression) -> Expression {
match value {
Expression::Number(n) => Expression::String(n.to_string()),
Expression::Boolean(b) => Expression::String(b.to_string()),
Expression::String(s) => Expression::String(s.clone()),
_ => Expression::String("None".to_string()),
}
}
pub fn to_int(value: &Expression) -> Expression {
match value {
Expression::Number(n) => Expression::Number(n.floor()),
Expression::String(s) => {
if let Ok(n) = s.parse::<f64>() {
Expression::Number(n.floor())
} else {
Expression::Number(0.0)
}
}
Expression::Boolean(b) => Expression::Number(if *b { 1.0 } else { 0.0 }),
_ => Expression::Number(0.0),
}
}
}