use crate::evaluator::RuntimeError;
use crate::value::Value;
fn get_number(val: &Value) -> Result<f64, RuntimeError> {
match val {
Value::Number(n) => Ok(*n),
_ => Err(RuntimeError::TypeErrorDetailed {
expected: "Number".to_string(),
got: format!("{:?}", val),
}),
}
}
pub fn calc_performance_pay(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let base_salary = get_number(&args[0])?;
let performance_coefficient = get_number(&args[1])?;
Ok(Value::Number(base_salary * performance_coefficient))
}
pub fn calc_annual_bonus(args: &[Value]) -> Result<Value, RuntimeError> {
if args.is_empty() {
return Err(RuntimeError::WrongArity {
expected: 1,
got: 0,
});
}
let monthly_salary = get_number(&args[0])?;
let months = if args.len() > 1 {
get_number(&args[1])?
} else {
12.0
};
let performance_coefficient = if args.len() > 2 {
get_number(&args[2])?
} else {
1.0
};
Ok(Value::Number(
monthly_salary * months * performance_coefficient,
))
}
pub fn calc_attendance_bonus(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let bonus = get_number(&args[0])?;
let attendance_rate = get_number(&args[1])?;
let threshold = if args.len() > 2 {
get_number(&args[2])?
} else {
1.0 };
if attendance_rate >= threshold {
Ok(Value::Number(bonus))
} else {
Ok(Value::Number(0.0))
}
}
pub fn calc_sales_commission(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let sales_amount = get_number(&args[0])?;
let commission_rate = get_number(&args[1])?;
let threshold = if args.len() > 2 {
get_number(&args[2])?
} else {
0.0
};
let commissionable = (sales_amount - threshold).max(0.0);
Ok(Value::Number(commissionable * commission_rate))
}
pub fn calc_project_bonus(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let project_amount = get_number(&args[0])?;
let allocation_ratio = get_number(&args[1])?;
Ok(Value::Number(project_amount * allocation_ratio))
}
pub fn calc_13th_salary(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let monthly_salary = get_number(&args[0])?;
let worked_months = get_number(&args[1])?;
let ratio = (worked_months / 12.0).min(1.0);
Ok(Value::Number(monthly_salary * ratio))
}