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_natural_days(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let start_day = get_number(&args[0])?;
let end_day = get_number(&args[1])?;
Ok(Value::Number(end_day - start_day + 1.0))
}
pub fn get_legal_pay_days(_args: &[Value]) -> Result<Value, RuntimeError> {
Ok(Value::Number(21.75))
}
pub fn calc_workdays(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let total_days = get_number(&args[0])?;
let weekend_days = get_number(&args[1])?;
Ok(Value::Number(total_days - weekend_days))
}
pub fn calc_weekend_days(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let total_days = get_number(&args[0])? as i32;
let start_weekday = get_number(&args[1])? as i32;
let mut weekend_count = 0;
for i in 0..total_days {
let weekday = ((start_weekday - 1 + i) % 7) + 1;
if weekday == 6 || weekday == 7 {
weekend_count += 1;
}
}
Ok(Value::Number(weekend_count as f64))
}
pub fn calc_holiday_days(args: &[Value]) -> Result<Value, RuntimeError> {
if args.is_empty() {
return Err(RuntimeError::WrongArity {
expected: 1,
got: 0,
});
}
let holiday_days = get_number(&args[0])?;
Ok(Value::Number(holiday_days))
}
pub fn is_workday(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let weekday = get_number(&args[0])? as i32;
let is_holiday = get_number(&args[1])? as i32;
let result = if is_holiday == 1 {
0 } else if (1..=5).contains(&weekday) {
1 } else {
0 };
Ok(Value::Number(result as f64))
}
pub fn is_weekend(args: &[Value]) -> Result<Value, RuntimeError> {
if args.is_empty() {
return Err(RuntimeError::WrongArity {
expected: 1,
got: 0,
});
}
let weekday = get_number(&args[0])? as i32;
let result = if weekday == 6 || weekday == 7 { 1 } else { 0 };
Ok(Value::Number(result as f64))
}
pub fn is_holiday(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() < 2 {
return Err(RuntimeError::WrongArity {
expected: 2,
got: args.len(),
});
}
let _date = get_number(&args[0])? as i32;
let holiday_indicator = get_number(&args[1])? as i32;
Ok(Value::Number(holiday_indicator as f64))
}
pub fn calc_work_hours(args: &[Value]) -> Result<Value, RuntimeError> {
if args.is_empty() {
return Err(RuntimeError::WrongArity {
expected: 1,
got: 0,
});
}
let work_days = get_number(&args[0])?;
let daily_hours = if args.len() > 1 {
get_number(&args[1])?
} else {
8.0
};
Ok(Value::Number(work_days * daily_hours))
}
pub fn calc_monthly_work_hours(args: &[Value]) -> Result<Value, RuntimeError> {
let monthly_days = if args.is_empty() {
21.75
} else {
get_number(&args[0])?
};
let daily_hours = if args.len() > 1 {
get_number(&args[1])?
} else {
8.0
};
Ok(Value::Number(monthly_days * daily_hours))
}
pub fn calc_annual_workdays(_args: &[Value]) -> Result<Value, RuntimeError> {
Ok(Value::Number(261.0))
}
pub fn calc_annual_pay_days(_args: &[Value]) -> Result<Value, RuntimeError> {
Ok(Value::Number(261.0))
}