use std::cmp::Ordering;
use std::sync::Arc;
use crate::context::IExpressionContext;
use crate::exceptions::TemplateProcessingException;
use crate::util::{Utf16String, ValidateError};
use super::{
BinaryOperationExpression, ComplexExpression, IStandardExpression,
StandardExpressionExecutionContext, StandardExpressionResult, TemplateValue,
binary_operation_expression::{collapse_java_null, compare_java_values, execute_operands},
};
pub struct GreaterThanExpression {
operation: BinaryOperationExpression,
}
impl GreaterThanExpression {
pub fn new(
left: Option<Arc<dyn IStandardExpression>>,
right: Option<Arc<dyn IStandardExpression>>,
) -> Result<Self, ValidateError> {
BinaryOperationExpression::new(left, right).map(|operation| Self { operation })
}
pub fn get_left(&self) -> &dyn IStandardExpression {
self.operation.get_left()
}
pub fn get_right(&self) -> &dyn IStandardExpression {
self.operation.get_right()
}
}
impl IStandardExpression for GreaterThanExpression {
fn get_string_representation(&self) -> StandardExpressionResult<Utf16String> {
self.operation
.get_string_representation(Some(&Utf16String::from_rust_str(">")))
}
fn execute_with_context(
&self,
context: &dyn IExpressionContext,
execution_context: &'static StandardExpressionExecutionContext,
) -> StandardExpressionResult<Option<Arc<TemplateValue>>> {
let (left, right) = execute_operands(&self.operation, context, execution_context)?;
let left = collapse_java_null(left);
let right = collapse_java_null(right);
let (Some(left), Some(right)) = (left.as_ref(), right.as_ref()) else {
return Err(comparison_null_error(
"GREATER THAN",
left.as_deref(),
right.as_deref(),
));
};
match compare_java_values(left, right)? {
Some(ordering) => Ok(Some(Arc::new(TemplateValue::Boolean(
ordering == Ordering::Greater,
)))),
None => Err(operation_error(
"GREATER THAN",
self.get_string_representation()?,
left.as_ref(),
right.as_ref(),
)),
}
}
fn is_complex(&self) -> bool {
true
}
}
impl ComplexExpression for GreaterThanExpression {}
impl super::GreaterLesserExpression for GreaterThanExpression {}
pub(crate) fn comparison_null_error(
operation: &str,
left: Option<&TemplateValue>,
right: Option<&TemplateValue>,
) -> crate::expression::StandardExpressionError {
Box::new(TemplateProcessingException::new(Some(format!(
"Cannot execute {operation} comparison: operands are \"{}\" and \"{}\"",
display_value(left),
display_value(right)
))))
}
pub(crate) fn operation_error(
operation: &str,
expression: Utf16String,
left: &TemplateValue,
right: &TemplateValue,
) -> crate::expression::StandardExpressionError {
Box::new(TemplateProcessingException::new(Some(format!(
"Cannot execute {operation} from Expression \"{}\". Left is \"{}\", right is \"{}\"",
expression.to_string_lossy(),
display_value(Some(left)),
display_value(Some(right))
))))
}
fn display_value(value: Option<&TemplateValue>) -> String {
value
.and_then(TemplateValue::to_utf16_string)
.unwrap_or_else(|| Utf16String::from_rust_str("null"))
.to_string_lossy()
}