1
use std::fmt::{self, Display, Formatter};
2

            
3
use thiserror::Error;
4

            
5
use crate::ast::Expression;
6

            
7
#[derive(Debug, Error)]
8
pub enum RuleApplicationError {
9
    #[error("Rule is not applicable")]
10
    RuleNotApplicable,
11
}
12

            
13
#[derive(Clone, Debug)]
14
pub struct Rule<'a> {
15
    pub name: &'a str,
16
    pub application: fn(&Expression) -> Result<Expression, RuleApplicationError>,
17
}
18

            
19
impl<'a> Rule<'a> {
20
    pub fn new(
21
        name: &'a str,
22
        application: fn(&Expression) -> Result<Expression, RuleApplicationError>,
23
    ) -> Self {
24
        Self { name, application }
25
    }
26

            
27
    pub fn apply(&self, expr: &Expression) -> Result<Expression, RuleApplicationError> {
28
        (self.application)(expr)
29
    }
30
}
31

            
32
impl<'a> Display for Rule<'a> {
33
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
34
        write!(f, "{}", self.name)
35
    }
36
}