use std::path::PathBuf;
use femstache_eval::{
Builtin, BuiltinFunction, EvalError, EvalErrorKind, EvalResult, StringValue, Value,
};
use femstache_parser::Span;
use femstache_types::{FunTy, Ty, TyId, TyStore};
pub struct Raw;
impl BuiltinFunction for Raw {
fn call(&self, args: &[Value]) -> EvalResult<Value> {
let [value] = &args else {
return Err(EvalError::new(
EvalErrorKind::InvalidType,
PathBuf::new(),
Span::new(0, 0),
));
};
let Some(s) = value.as_string() else {
return Err(EvalError::new(
EvalErrorKind::InvalidType,
PathBuf::new(),
Span::new(0, 0),
));
};
Ok(Value::String(match s {
StringValue::Regular(s) => StringValue::Raw(s.clone()),
StringValue::Raw(s) => StringValue::Raw(s.clone()),
}))
}
}
pub struct ShowInt;
impl BuiltinFunction for ShowInt {
fn call(&self, args: &[Value]) -> EvalResult<Value> {
let [value] = &args else {
return Err(EvalError::new(
EvalErrorKind::InvalidType,
PathBuf::new(),
Span::new(0, 0),
));
};
let Some(i) = value.as_int() else {
return Err(EvalError::new(
EvalErrorKind::InvalidType,
PathBuf::new(),
Span::new(0, 0),
));
};
Ok(Value::string(i.to_string()))
}
}
pub struct ShowBool;
impl BuiltinFunction for ShowBool {
fn call(&self, args: &[Value]) -> EvalResult<Value> {
let [value] = &args else {
return Err(EvalError::new(
EvalErrorKind::InvalidType,
PathBuf::new(),
Span::new(0, 0),
));
};
let Some(b) = value.as_bool() else {
return Err(EvalError::new(
EvalErrorKind::InvalidType,
PathBuf::new(),
Span::new(0, 0),
));
};
Ok(Value::string(b.to_string()))
}
}
pub fn add_builtins(store: &mut TyStore) -> Vec<(String, Builtin)> {
let mut builtins = Vec::new();
let raw_id = store.intern(Ty::Fun(FunTy::new([TyId::STRING], TyId::STRING)));
let show_int_id = store.intern(Ty::Fun(FunTy::new([TyId::INT], TyId::STRING)));
let show_bool_id = store.intern(Ty::Fun(FunTy::new([TyId::BOOL], TyId::STRING)));
builtins.push(("raw".to_owned(), Builtin::new(raw_id, Raw)));
builtins.push(("show_int".to_owned(), Builtin::new(show_int_id, ShowInt)));
builtins.push(("show_bool".to_owned(), Builtin::new(show_bool_id, ShowBool)));
builtins
}