#![doc = include_str!("../README.md")]
#[cfg(feature = "proc_macro")]
pub use compare_variables_macro::compare_variables;
#[derive(Clone)]
pub struct ComparisonError<T: PartialOrd> {
first_val: ComparisonValue<T>,
comp_first_to_second: ComparisonOperator,
second_val: ComparisonValue<T>,
comp_second_to_third: ComparisonOperator,
third_val: Option<ComparisonValue<T>>,
}
impl<T: PartialOrd> ComparisonError<T> {
pub fn new(
first_val: ComparisonValue<T>,
comp_first_to_second: ComparisonOperator,
second_val: ComparisonValue<T>,
comp_second_to_third: ComparisonOperator,
third_val: Option<ComparisonValue<T>>,
) -> Result<(), Self> {
if !comp_first_to_second.is_true(&first_val.value, &second_val.value) {
return Err(Self {
first_val,
comp_first_to_second,
second_val,
comp_second_to_third,
third_val,
});
}
if let Some(third_val) = third_val {
if !comp_second_to_third.is_true(&second_val.value, &third_val.value) {
return Err(Self {
first_val,
comp_first_to_second,
second_val,
comp_second_to_third,
third_val: Some(third_val),
});
}
};
return Ok(());
}
pub fn first_val(&self) -> &ComparisonValue<T> {
return &self.first_val;
}
pub fn second_val(&self) -> &ComparisonValue<T> {
return &self.second_val;
}
pub fn third_val(&self) -> Option<&ComparisonValue<T>> {
return self.third_val.as_ref();
}
}
impl<T: PartialOrd + std::fmt::Debug> std::error::Error for ComparisonError<T> {}
impl<T: PartialOrd + std::fmt::Debug> std::fmt::Debug for ComparisonError<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return std::fmt::Display::fmt(self, f);
}
}
impl<T: PartialOrd + std::fmt::Debug> std::fmt::Display for ComparisonError<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"`{} {} {}",
self.first_val, self.comp_first_to_second, self.second_val
)?;
if let Some(third_val) = self.third_val.as_ref() {
write!(f, " {} {}", self.comp_second_to_third, third_val)?;
}
write!(f, "` is false")
}
}
#[derive(Debug, Clone)]
pub struct ComparisonValue<T: PartialOrd> {
pub value: T,
pub variable_name: Option<&'static str>,
}
impl<T: PartialOrd> ComparisonValue<T> {
pub fn new(value: T, variable_name: Option<&'static str>) -> Self {
return Self {
value,
variable_name,
};
}
}
impl<T: PartialOrd + std::fmt::Debug> std::fmt::Display for ComparisonValue<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(name) = self.variable_name.as_ref() {
write!(f, "{name} (value: ")?;
write!(f, "{:?})", self.value)?;
} else {
write!(f, "{:?}", self.value)?;
}
return Ok(());
}
}
#[repr(u8)]
#[derive(Debug, Clone, Copy)]
pub enum ComparisonOperator {
Lesser,
LesserOrEqual,
Equal,
Inequal,
GreaterOrEqual,
Greater,
}
impl ComparisonOperator {
pub fn as_str(&self) -> &'static str {
match self {
ComparisonOperator::Lesser => "<",
ComparisonOperator::LesserOrEqual => "<=",
ComparisonOperator::Equal => "==",
ComparisonOperator::Inequal => "!=",
ComparisonOperator::GreaterOrEqual => ">=",
ComparisonOperator::Greater => ">",
}
}
pub fn is_true<T: PartialOrd>(&self, first_val: &T, second_val: &T) -> bool {
match self {
ComparisonOperator::Lesser => return first_val < second_val,
ComparisonOperator::LesserOrEqual => return first_val <= second_val,
ComparisonOperator::Equal => return first_val == second_val,
ComparisonOperator::Inequal => return first_val != second_val,
ComparisonOperator::GreaterOrEqual => return first_val >= second_val,
ComparisonOperator::Greater => return first_val > second_val,
}
}
}
impl From<&ComparisonOperator> for &'static str {
fn from(value: &ComparisonOperator) -> Self {
return value.as_str();
}
}
impl AsRef<str> for ComparisonOperator {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl std::fmt::Display for ComparisonOperator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
pub trait ComparisonErrorTrait: std::error::Error + Sync + Send + std::any::Any {
fn fmt_first_val(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
fn fmt_second_val(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
fn fmt_third_val(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
fn comp_first_to_second(&self) -> ComparisonOperator;
fn comp_second_to_third(&self) -> ComparisonOperator;
}
impl<T: PartialOrd + std::fmt::Debug + Sync + Send + 'static> ComparisonErrorTrait
for ComparisonError<T>
{
fn fmt_first_val(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return std::fmt::Display::fmt(self.first_val(), f);
}
fn fmt_second_val(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return std::fmt::Display::fmt(self.second_val(), f);
}
fn fmt_third_val(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.third_val() {
Some(v) => return std::fmt::Display::fmt(v, f),
None => return Err(std::fmt::Error),
}
}
fn comp_first_to_second(&self) -> ComparisonOperator {
return self.comp_first_to_second;
}
fn comp_second_to_third(&self) -> ComparisonOperator {
return self.comp_second_to_third;
}
}