use femstache_eval::{BuiltinFunction, EvalError, EvalErrorKind, EvalResult, StringValue, Value};
use femstache_parser::Span;
use femstache_types::{TyId, TyStore};
pub struct Raw;
impl BuiltinFunction for Raw {
fn types(&self, _store: &TyStore) -> (TyId, TyId) {
(TyId::STRING, TyId::STRING)
}
fn call(&self, value: Value) -> EvalResult<Value> {
let Some(s) = value.into_string() else {
return Err(EvalError::new(EvalErrorKind::InvalidType, Span::new(0, 0)));
};
Ok(Value::String(match s {
StringValue::Regular(s) => StringValue::Raw(s),
StringValue::Raw(s) => StringValue::Raw(s),
}))
}
}
pub struct ShowInt;
impl BuiltinFunction for ShowInt {
fn types(&self, _store: &TyStore) -> (TyId, TyId) {
(TyId::INT, TyId::STRING)
}
fn call(&self, value: Value) -> EvalResult<Value> {
let Some(i) = value.as_int() else {
return Err(EvalError::new(EvalErrorKind::InvalidType, Span::new(0, 0)));
};
Ok(Value::string(i.to_string()))
}
}
pub struct ShowBool;
impl BuiltinFunction for ShowBool {
fn types(&self, _store: &TyStore) -> (TyId, TyId) {
(TyId::BOOL, TyId::STRING)
}
fn call(&self, value: Value) -> EvalResult<Value> {
let Some(b) = value.as_bool() else {
return Err(EvalError::new(EvalErrorKind::InvalidType, Span::new(0, 0)));
};
Ok(Value::string(b.to_string()))
}
}
pub fn make_builtins() -> Vec<(String, Value)> {
let mut builtins = Vec::new();
builtins.push(("raw".to_owned(), Value::builtin(Raw)));
builtins.push(("show_int".to_owned(), Value::builtin(ShowInt)));
builtins.push(("show_bool".to_owned(), Value::builtin(ShowBool)));
builtins
}