use crate::core::Environment;
use crate::error::{Result, TemplateError};
use crate::template::TModel;
use crate::template::TemplateMethodModelEx;
pub struct ObjectConstructorFn;
impl TemplateMethodModelEx for ObjectConstructorFn {
fn exec(&self, _env: &mut Environment, args: Vec<TModel>) -> Result<TModel> {
let Some(first) = args.first() else {
return Err(TemplateError::misc(
"No error description was specified for this error; low-level message: java.lang.IllegalArgumentException: Object constructor needs at least 1 argument.",
));
};
let class_name = arg_to_string(first)?;
let rest = &args[1..];
match class_name.as_str() {
"java.lang.String" => {
let Some(s) = rest.first() else {
return Err(no_such_method(&class_name, rest));
};
Ok(TModel::from_scalar(arg_to_string(s)?))
}
"java.lang.Integer" | "java.lang.Long" => {
let Some(n) = rest.first() else {
return Err(no_such_method(&class_name, rest));
};
if n.is_number() {
Ok(TModel::from_scalar(arg_to_string(n)?))
} else {
Err(no_such_method(&class_name, rest))
}
}
_ => Err(TemplateError::misc(format!(
"No error description was specified for this error; low-level message: java.lang.ClassNotFoundException: {class_name}"
))),
}
}
}
fn no_such_method(class_name: &str, ctor_args: &[TModel]) -> TemplateError {
let arg_desc: Vec<&str> = ctor_args.iter().map(|m| m.type_name).collect();
TemplateError::misc(format!(
"No error description was specified for this error; low-level message: java.lang.NoSuchMethodException: {class_name}.<init>({}).",
arg_desc.join(", ")
))
}
pub(crate) fn arg_to_string(m: &TModel) -> Result<String> {
if let Some(s) = &m.scalar {
return s.as_string();
}
if let Some(n) = &m.number {
return n.as_number().map(|n| n.to_plain_string());
}
Err(TemplateError::misc(format!(
"Expected a string or number, but this has evaluated to a {}",
m.type_name
)))
}