use crate::value::Value;
use alloc::string::ToString as _;
use super::common;
use super::evaluator::RbacBuiltinError;
#[cfg(feature = "regex")]
use regex::Regex;
pub(super) fn string_equals(left: &Value, right: &Value) -> Result<bool, RbacBuiltinError> {
if common::is_collection(right) && !common::is_collection(left) {
return Ok(common::collection_contains(right, left));
}
if common::is_collection(left) && !common::is_collection(right) {
return Ok(common::collection_contains(left, right));
}
Ok(left == right)
}
pub(super) fn string_equals_ignore_case(
left: &Value,
right: &Value,
) -> Result<bool, RbacBuiltinError> {
if common::is_collection(right) && !common::is_collection(left) {
return Ok(common::collection_contains_case_insensitive(right, left));
}
if common::is_collection(left) && !common::is_collection(right) {
return Ok(common::collection_contains_case_insensitive(left, right));
}
let left_str = common::value_as_string(left, "StringEqualsIgnoreCase")?;
let right_str = common::value_as_string(right, "StringEqualsIgnoreCase")?;
Ok(left_str.eq_ignore_ascii_case(&right_str))
}
pub(super) fn string_like(left: &Value, right: &Value) -> Result<bool, RbacBuiltinError> {
let value = common::value_as_string(left, "StringLike")?;
let pattern = common::value_as_string(right, "StringLike")?;
Ok(common::simple_wildcard_match(&pattern, &value))
}
pub(super) fn string_starts_with(left: &Value, right: &Value) -> Result<bool, RbacBuiltinError> {
let value = common::value_as_string(left, "StringStartsWith")?;
let prefix = common::value_as_string(right, "StringStartsWith")?;
Ok(value.starts_with(&prefix))
}
pub(super) fn string_ends_with(left: &Value, right: &Value) -> Result<bool, RbacBuiltinError> {
let value = common::value_as_string(left, "StringEndsWith")?;
let suffix = common::value_as_string(right, "StringEndsWith")?;
Ok(value.ends_with(&suffix))
}
pub(super) fn string_contains(left: &Value, right: &Value) -> Result<bool, RbacBuiltinError> {
let value = common::value_as_string(left, "StringContains")?;
let needle = common::value_as_string(right, "StringContains")?;
Ok(value.contains(&needle))
}
pub(super) fn string_matches(left: &Value, right: &Value) -> Result<bool, RbacBuiltinError> {
let value = common::value_as_string(left, "StringMatches")?;
let pattern = common::value_as_string(right, "StringMatches")?;
#[cfg(feature = "regex")]
{
let regex = Regex::new(&pattern).map_err(|err| RbacBuiltinError::new(err.to_string()))?;
Ok(regex.is_match(&value))
}
#[cfg(not(feature = "regex"))]
{
Ok(value == pattern)
}
}
pub(super) fn guid_equals(
left: &Value,
right: &Value,
name: &'static str,
) -> Result<bool, RbacBuiltinError> {
let lhs = common::value_as_string(left, name)?;
let rhs = common::value_as_string(right, name)?;
Ok(lhs.eq_ignore_ascii_case(&rhs))
}