use anyhow::Result;
use super::super::types::SwrlArgument;
use super::utils::*;
pub(crate) fn builtin_day_time_duration(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"dayTimeDuration requires exactly 2 arguments"
));
}
let duration_str = extract_string_value(&args[0])?;
let expected = extract_string_value(&args[1])?;
Ok(duration_str == expected)
}
pub(crate) fn builtin_year_month_duration(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"yearMonthDuration requires exactly 2 arguments"
));
}
let duration_str = extract_string_value(&args[0])?;
let expected = extract_string_value(&args[1])?;
Ok(duration_str == expected)
}
pub(crate) fn builtin_date_time(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!("dateTime requires exactly 2 arguments"));
}
let datetime_str = extract_string_value(&args[0])?;
let expected = extract_string_value(&args[1])?;
Ok(datetime_str == expected)
}
pub(crate) fn builtin_date_add(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 4 {
return Err(anyhow::anyhow!(
"dateAdd requires exactly 4 arguments: date, duration, unit, result"
));
}
let date_str = extract_string_value(&args[0])?;
let duration = extract_numeric_value(&args[1])? as i64;
let unit = extract_string_value(&args[2])?;
let expected_result = extract_string_value(&args[3])?;
if let Ok(timestamp) = date_str.parse::<i64>() {
let seconds_to_add = match unit.as_str() {
"seconds" => duration,
"minutes" => duration * 60,
"hours" => duration * 3600,
"days" => duration * 86400,
"weeks" => duration * 604800,
_ => return Err(anyhow::anyhow!("Unsupported time unit: {}", unit)),
};
let result_timestamp = timestamp + seconds_to_add;
Ok(result_timestamp.to_string() == expected_result)
} else {
Ok(false)
}
}
pub(crate) fn builtin_date_diff(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 3 {
return Err(anyhow::anyhow!(
"dateDiff requires exactly 3 arguments: date1, date2, result"
));
}
let date1_str = extract_string_value(&args[0])?;
let date2_str = extract_string_value(&args[1])?;
let expected_diff = extract_numeric_value(&args[2])?;
if let (Ok(timestamp1), Ok(timestamp2)) = (date1_str.parse::<i64>(), date2_str.parse::<i64>()) {
let diff_seconds = (timestamp2 - timestamp1).abs() as f64;
Ok((diff_seconds - expected_diff).abs() < 1.0) } else {
Ok(false)
}
}
pub(crate) fn builtin_now(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 1 {
return Err(anyhow::anyhow!("now requires exactly 1 argument: result"));
}
let expected_result = extract_string_value(&args[0])?;
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_err(|e| anyhow::anyhow!("Time error: {}", e))?
.as_secs();
if let Ok(expected_timestamp) = expected_result.parse::<u64>() {
Ok((now as i64 - expected_timestamp as i64).abs() <= 1)
} else {
Ok(false)
}
}
pub(crate) fn builtin_temporal_before(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"temporal:before requires exactly 2 arguments: time1, time2"
));
}
let time1 = extract_numeric_value(&args[0])?;
let time2 = extract_numeric_value(&args[1])?;
Ok(time1 < time2)
}
pub(crate) fn builtin_temporal_after(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"temporal:after requires exactly 2 arguments: time1, time2"
));
}
let time1 = extract_numeric_value(&args[0])?;
let time2 = extract_numeric_value(&args[1])?;
Ok(time1 > time2)
}
pub(crate) fn builtin_temporal_during(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 3 {
return Err(anyhow::anyhow!(
"temporal:during requires exactly 3 arguments: time, interval_start, interval_end"
));
}
let time = extract_numeric_value(&args[0])?;
let interval_start = extract_numeric_value(&args[1])?;
let interval_end = extract_numeric_value(&args[2])?;
Ok(time >= interval_start && time <= interval_end)
}
pub(crate) fn builtin_temporal_overlaps(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 4 {
return Err(anyhow::anyhow!(
"temporal:overlaps requires exactly 4 arguments: start1, end1, start2, end2"
));
}
let start1 = extract_numeric_value(&args[0])?;
let end1 = extract_numeric_value(&args[1])?;
let start2 = extract_numeric_value(&args[2])?;
let end2 = extract_numeric_value(&args[3])?;
Ok(start1 < end2 && start2 < end1)
}
pub(crate) fn builtin_temporal_meets(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 4 {
return Err(anyhow::anyhow!(
"temporal:meets requires exactly 4 arguments: start1, end1, start2, end2"
));
}
let _start1 = extract_numeric_value(&args[0])?;
let end1 = extract_numeric_value(&args[1])?;
let start2 = extract_numeric_value(&args[2])?;
let _end2 = extract_numeric_value(&args[3])?;
Ok((end1 - start2).abs() < f64::EPSILON)
}
pub(crate) fn builtin_interval_duration(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 3 {
return Err(anyhow::anyhow!(
"temporal:intervalDuration requires exactly 3 arguments: start, end, duration"
));
}
let start = extract_numeric_value(&args[0])?;
let end = extract_numeric_value(&args[1])?;
let expected_duration = extract_numeric_value(&args[2])?;
let actual_duration = (end - start).abs();
Ok((actual_duration - expected_duration).abs() < f64::EPSILON)
}
pub(crate) fn builtin_date(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 4 {
return Err(anyhow::anyhow!(
"date requires exactly 4 arguments: year, month, day, result"
));
}
let year = extract_numeric_value(&args[0])? as i32;
let month = extract_numeric_value(&args[1])? as u32;
let day = extract_numeric_value(&args[2])? as u32;
let expected = extract_string_value(&args[3])?;
let result = format!("{:04}-{:02}-{:02}", year, month, day);
Ok(result == expected)
}
pub(crate) fn builtin_time(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 4 {
return Err(anyhow::anyhow!(
"time requires exactly 4 arguments: hour, minute, second, result"
));
}
let hour = extract_numeric_value(&args[0])? as u32;
let minute = extract_numeric_value(&args[1])? as u32;
let second = extract_numeric_value(&args[2])? as u32;
let expected = extract_string_value(&args[3])?;
let result = format!("{:02}:{:02}:{:02}", hour, minute, second);
Ok(result == expected)
}
pub(crate) fn builtin_year(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"year requires exactly 2 arguments: date, result"
));
}
let date_str = extract_string_value(&args[0])?;
let expected_year = extract_numeric_value(&args[1])? as i32;
if let Some(year_part) = date_str.split('-').next() {
if let Ok(year) = year_part.parse::<i32>() {
return Ok(year == expected_year);
}
}
Ok(false)
}
pub(crate) fn builtin_month(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"month requires exactly 2 arguments: date, result"
));
}
let date_str = extract_string_value(&args[0])?;
let expected_month = extract_numeric_value(&args[1])? as u32;
let parts: Vec<&str> = date_str.split('-').collect();
if parts.len() >= 2 {
if let Ok(month) = parts[1].parse::<u32>() {
return Ok(month == expected_month);
}
}
Ok(false)
}
pub(crate) fn builtin_day(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"day requires exactly 2 arguments: date, result"
));
}
let date_str = extract_string_value(&args[0])?;
let expected_day = extract_numeric_value(&args[1])? as u32;
let parts: Vec<&str> = date_str.split('-').collect();
if parts.len() >= 3 {
if let Ok(day) = parts[2].parse::<u32>() {
return Ok(day == expected_day);
}
}
Ok(false)
}
pub(crate) fn builtin_hour(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"hour requires exactly 2 arguments: time, result"
));
}
let time_str = extract_string_value(&args[0])?;
let expected_hour = extract_numeric_value(&args[1])? as u32;
if let Some(hour_part) = time_str.split(':').next() {
if let Ok(hour) = hour_part.parse::<u32>() {
return Ok(hour == expected_hour);
}
}
Ok(false)
}
pub(crate) fn builtin_minute(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"minute requires exactly 2 arguments: time, result"
));
}
let time_str = extract_string_value(&args[0])?;
let expected_minute = extract_numeric_value(&args[1])? as u32;
let parts: Vec<&str> = time_str.split(':').collect();
if parts.len() >= 2 {
if let Ok(minute) = parts[1].parse::<u32>() {
return Ok(minute == expected_minute);
}
}
Ok(false)
}
pub(crate) fn builtin_second(args: &[SwrlArgument]) -> Result<bool> {
if args.len() != 2 {
return Err(anyhow::anyhow!(
"second requires exactly 2 arguments: time, result"
));
}
let time_str = extract_string_value(&args[0])?;
let expected_second = extract_numeric_value(&args[1])? as u32;
let parts: Vec<&str> = time_str.split(':').collect();
if parts.len() >= 3 {
if let Ok(second) = parts[2].parse::<u32>() {
return Ok(second == expected_second);
}
}
Ok(false)
}