use std::{
    fmt,
    ops::{Add, Not},
};

use crate::vm::value::NumberValue;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BooleanValue(pub bool);

impl From<bool> for BooleanValue {
    fn from(value: bool) -> Self {
        Self(value)
    }
}

impl Not for BooleanValue {
    type Output = Self;

    fn not(self) -> Self::Output {
        Self(!self.0)
    }
}

impl Add for BooleanValue {
    type Output = NumberValue;

    fn add(self, rhs: Self) -> Self::Output {
        NumberValue::Int(self.0 as i64 + rhs.0 as i64)
    }
}

impl fmt::Display for BooleanValue {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.0 {
            true => write!(f, "#T"),
            false => write!(f, "#F"),
        }
    }
}
