1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use std::fmt::{Debug, Formatter};
use std::sync::{Arc, RwLock};

use derivative::Derivative;
use schemars::JsonSchema;
use serde::Serialize;
use serde_with::skip_serializing_none;

use crate::rule_engine::{Rule, RuleSet};
use crate::solver::SolverFamily;
use crate::stats::Stats;

#[skip_serializing_none]
#[derive(Clone, Serialize, Default, Derivative, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[derivative(Eq, PartialEq)]
#[non_exhaustive]
pub struct Context<'a> {
    pub target_solver_family: Option<SolverFamily>,

    pub file_name: Option<String>,

    pub extra_rule_set_names: Vec<String>,

    #[serde(skip)]
    pub rules: Vec<&'a Rule<'a>>,

    #[serde(skip)]
    pub rule_sets: Vec<&'a RuleSet<'a>>,

    #[derivative(PartialEq = "ignore")]
    pub stats: Stats,
}

impl<'a> Context<'a> {
    pub fn new(
        target_solver_family: SolverFamily,
        extra_rule_set_names: Vec<String>,
        rules: Vec<&'a Rule<'a>>,
        rule_sets: Vec<&'a RuleSet<'a>>,
    ) -> Self {
        Context {
            target_solver_family: Some(target_solver_family),
            extra_rule_set_names,
            rules,
            rule_sets,
            stats: Default::default(),
            ..Default::default()
        }
    }
}

impl Context<'static> {
    pub fn new_ptr(
        target_solver_family: SolverFamily,
        extra_rule_set_names: Vec<String>,
        rules: Vec<&'static Rule<'static>>,
        rule_sets: Vec<&'static RuleSet<'static>>,
    ) -> Arc<RwLock<Context<'static>>> {
        Arc::new(RwLock::new(Context::new(
            target_solver_family,
            extra_rule_set_names,
            rules,
            rule_sets,
        )))
    }
}

impl<'a> Debug for Context<'a> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let target_solver_family: Option<SolverFamily> = self.target_solver_family;
        let extra_rule_set_names: Vec<String> = self.extra_rule_set_names.clone();
        let rules: Vec<&str> = self.rules.iter().map(|r| r.name).collect();
        let rule_sets: Vec<&str> = self.rule_sets.iter().map(|r| r.name).collect();

        write!(
            f,
            "Context {{\n\
            \ttarget_solver_family: {:?}\n\
            \textra_rule_set_names: {:?}\n\
            \trules: {:?}\n\
            \trule_sets: {:?}\n\
        }}",
            target_solver_family, extra_rule_set_names, rules, rule_sets
        )
    }
}