use core::fmt;
use std::borrow::Cow;
use bounded_static::ToStatic;
use super::pretty_decimal::PrettyDecimal;
use crate::datamodel;
#[derive(Debug, PartialEq, Eq, Clone, ToStatic)]
pub struct Amount<'i> {
pub value: PrettyDecimal,
pub commodity: Cow<'i, str>,
}
impl<'i> From<&'i datamodel::Amount> for Amount<'i> {
fn from(value: &'i datamodel::Amount) -> Self {
Self {
value: PrettyDecimal::unformatted(value.value),
commodity: Cow::Borrowed(&value.commodity),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, ToStatic)]
pub enum ValueExpr<'i> {
Paren(Expr<'i>),
Amount(Amount<'i>),
}
impl<'i> From<Amount<'i>> for ValueExpr<'i> {
fn from(v: Amount<'i>) -> Self {
ValueExpr::Amount(v)
}
}
impl<'i> From<&'i datamodel::Amount> for ValueExpr<'i> {
fn from(value: &'i datamodel::Amount) -> Self {
ValueExpr::Amount(value.into())
}
}
#[derive(Debug, PartialEq, Eq, Clone, ToStatic)]
pub enum Expr<'i> {
Unary(UnaryOpExpr<'i>),
Binary(BinaryOpExpr<'i>),
Value(Box<ValueExpr<'i>>),
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, ToStatic)]
pub enum UnaryOp {
Negate,
}
impl fmt::Display for UnaryOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let op = match self {
UnaryOp::Negate => "-",
};
write!(f, "{}", op)
}
}
#[derive(Debug, PartialEq, Eq, Clone, ToStatic)]
pub struct UnaryOpExpr<'i> {
pub op: UnaryOp,
pub expr: Box<Expr<'i>>,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, strum::EnumIter, ToStatic)]
pub enum BinaryOp {
Add,
Sub,
Mul,
Div,
}
impl fmt::Display for BinaryOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let op = match self {
BinaryOp::Add => "+",
BinaryOp::Sub => "-",
BinaryOp::Mul => "*",
BinaryOp::Div => "/",
};
write!(f, "{}", op)
}
}
#[derive(Debug, PartialEq, Eq, Clone, ToStatic)]
pub struct BinaryOpExpr<'i> {
pub op: BinaryOp,
pub lhs: Box<Expr<'i>>,
pub rhs: Box<Expr<'i>>,
}