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_overtime_pay(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 3 {
return Err(RuntimeError::WrongArity {
expected: 3,
got: args.len(),
});
}
let hourly_rate = get_number(&args[0])?;
let hours = get_number(&args[1])?;
let multiplier = get_number(&args[2])?;
if hours < 0.0 {
return Err(RuntimeError::InvalidOperation(
"加班小时数不能为负数".to_string(),
));
}
Ok(Value::Number(hourly_rate * hours * multiplier))
}
pub fn calc_weekday_overtime(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 hours = get_number(&args[1])?;
if hours < 0.0 {
return Err(RuntimeError::InvalidOperation(
"加班小时数不能为负数".to_string(),
));
}
let hourly_rate = monthly_salary / 21.75 / 8.0;
Ok(Value::Number(hourly_rate * hours * 1.5))
}
pub fn calc_weekend_overtime(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 hours = get_number(&args[1])?;
if hours < 0.0 {
return Err(RuntimeError::InvalidOperation(
"加班小时数不能为负数".to_string(),
));
}
let hourly_rate = monthly_salary / 21.75 / 8.0;
Ok(Value::Number(hourly_rate * hours * 2.0))
}
pub fn calc_holiday_overtime(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 hours = get_number(&args[1])?;
if hours < 0.0 {
return Err(RuntimeError::InvalidOperation(
"加班小时数不能为负数".to_string(),
));
}
let hourly_rate = monthly_salary / 21.75 / 8.0;
Ok(Value::Number(hourly_rate * hours * 3.0))
}
pub fn calc_total_overtime(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 3 {
return Err(RuntimeError::WrongArity {
expected: 3,
got: args.len(),
});
}
let weekday = get_number(&args[0])?;
let weekend = get_number(&args[1])?;
let holiday = get_number(&args[2])?;
Ok(Value::Number(weekday + weekend + holiday))
}