use proc_macro2::Ident;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Sign {
Positive,
Negative,
Any,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Bounds {
pub lower: Option<f64>,
pub upper: Option<f64>,
}
impl Bounds {
const EPSILON: f64 = 1e-10;
pub const fn is_bounded(&self) -> bool {
self.lower.is_some() && self.upper.is_some()
}
pub fn is_normalized(&self) -> bool {
matches!(self, Bounds { lower: Some(l), upper: Some(u) }
if (*l - 0.0).abs() < Self::EPSILON && (*u - 1.0).abs() < Self::EPSILON)
}
pub fn is_symmetric(&self) -> bool {
matches!(self, Bounds { lower: Some(l), upper: Some(u) }
if (*l - (-1.0)).abs() < Self::EPSILON && (*u - 1.0).abs() < Self::EPSILON)
}
pub fn is_negative_normalized(&self) -> bool {
matches!(self, Bounds { lower: Some(l), upper: Some(u) }
if (*l - (-1.0)).abs() < Self::EPSILON && (*u - 0.0).abs() < Self::EPSILON)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ArithmeticOp {
Add,
Sub,
Mul,
Div,
}
#[derive(Debug, Clone)]
pub struct ArithmeticResult {
pub output_type: Ident,
pub is_safe: bool,
}
pub struct TypeConfig {
pub constraints: Vec<ConstraintDef>,
pub constraint_types: Vec<TypeDef>,
pub arithmetic_results: HashMap<(ArithmeticOp, String, String), ArithmeticResult>,
pub type_aliases: Vec<TypeAliasDef>,
}
pub struct ConstraintDef {
pub name: Ident,
pub neg_constraint_name: Option<Ident>,
pub raw_conditions: Vec<String>,
pub sign: Sign,
pub bounds: Bounds,
pub excludes_zero: bool,
}
pub struct TypeDef {
pub type_name: Ident,
pub float_types: Vec<Ident>,
pub constraint_name: Ident,
}
pub fn get_standard_arithmetic_ops() -> [(
ArithmeticOp,
&'static str,
&'static str,
proc_macro2::TokenStream,
); 4] {
use quote::quote;
[
(ArithmeticOp::Add, "Add", "add", quote! { + }),
(ArithmeticOp::Sub, "Sub", "sub", quote! { - }),
(ArithmeticOp::Mul, "Mul", "mul", quote! { * }),
(ArithmeticOp::Div, "Div", "div", quote! { / }),
]
}
#[derive(Debug, Clone)]
pub struct TypeAliasDef {
pub original_name: Ident,
pub alias_name: Ident,
}