1
#![allow(unused)]
2

            
3
use conjure_cp::settings::{Parser, QuantifiedExpander, Rewriter, SolverFamily};
4
use serde::Deserialize;
5
use std::str::FromStr;
6

            
7
6936
fn parse_values<T>(values: &[String]) -> Result<Vec<T>, String>
8
6936
where
9
6936
    T: FromStr<Err = String>,
10
{
11
7864
    values.iter().map(|value| value.parse()).collect()
12
6936
}
13

            
14
17110
fn deserialize_string_or_vec<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
15
17110
where
16
17110
    D: serde::Deserializer<'de>,
17
{
18
    #[derive(Deserialize)]
19
    #[serde(untagged)]
20
    enum StringOrVec {
21
        String(String),
22
        Vec(Vec<String>),
23
    }
24

            
25
17110
    Ok(match StringOrVec::deserialize(deserializer)? {
26
2
        StringOrVec::String(s) => vec![s],
27
17108
        StringOrVec::Vec(v) => v,
28
    })
29
17110
}
30

            
31
5142
fn default_true() -> bool {
32
5142
    true
33
5142
}
34

            
35
10412
fn default_minion_discrete_threshold() -> usize {
36
10412
    conjure_cp::settings::DEFAULT_MINION_DISCRETE_THRESHOLD
37
10412
}
38

            
39
#[derive(Deserialize, Debug)]
40
#[serde(default)]
41
#[serde(deny_unknown_fields)]
42
pub struct TestConfig {
43
    #[serde(
44
        default,
45
        rename = "parser",
46
        deserialize_with = "deserialize_string_or_vec"
47
    )]
48
    pub parser: Vec<String>, // Stage 1a: list of parsers (tree-sitter or via-conjure)
49

            
50
    #[serde(
51
        default,
52
        rename = "rewriter",
53
        deserialize_with = "deserialize_string_or_vec"
54
    )]
55
    pub rewriter: Vec<String>,
56
    #[serde(
57
        default,
58
        rename = "comprehension-expander",
59
        deserialize_with = "deserialize_string_or_vec"
60
    )]
61
    pub comprehension_expander: Vec<String>,
62
    #[serde(
63
        default,
64
        rename = "solver",
65
        deserialize_with = "deserialize_string_or_vec"
66
    )]
67
    pub solver: Vec<String>,
68

            
69
    #[serde(
70
        default = "default_minion_discrete_threshold",
71
        rename = "minion-discrete-threshold"
72
    )]
73
    pub minion_discrete_threshold: usize,
74

            
75
    #[serde(default = "default_true", rename = "validate-with-conjure")]
76
    pub validate_with_conjure: bool,
77
}
78

            
79
impl Default for TestConfig {
80
5228
    fn default() -> Self {
81
5228
        Self {
82
5228
            parser: vec!["tree-sitter".to_string(), "via-conjure".to_string()],
83
5228
            rewriter: vec!["naive".to_string()],
84
5228
            comprehension_expander: vec![
85
5228
                "native".to_string(),
86
5228
                "via-solver".to_string(),
87
5228
                "via-solver-ac".to_string(),
88
5228
            ],
89
5228
            solver: {
90
5228
                let mut solvers = vec![
91
5228
                    "minion".to_string(),
92
5228
                    "sat-log".to_string(),
93
5228
                    "sat-direct".to_string(),
94
5228
                    "sat-order".to_string(),
95
5228
                ];
96
5228
                #[cfg(feature = "smt")]
97
5228
                {
98
5228
                    solvers.extend([
99
5228
                        "smt".to_string(),
100
5228
                        "smt-lia-arrays-nodiscrete".to_string(),
101
5228
                        "smt-lia-atomic".to_string(),
102
5228
                        "smt-lia-atomic-nodiscrete".to_string(),
103
5228
                        "smt-bv-arrays".to_string(),
104
5228
                        "smt-bv-arrays-nodiscrete".to_string(),
105
5228
                        "smt-bv-atomic".to_string(),
106
5228
                        "smt-bv-atomic-nodiscrete".to_string(),
107
5228
                    ]);
108
5228
                }
109
5228
                solvers
110
5228
            },
111
5228
            minion_discrete_threshold: default_minion_discrete_threshold(),
112
5228
            validate_with_conjure: true,
113
5228
        }
114
5228
    }
115
}
116

            
117
impl TestConfig {
118
1812
    pub fn configured_parsers(&self) -> Result<Vec<Parser>, String> {
119
1812
        parse_values(&self.parser)
120
1812
    }
121

            
122
1708
    pub fn configured_rewriters(&self) -> Result<Vec<Rewriter>, String> {
123
1708
        if self.rewriter.is_empty() {
124
            return Err("setting 'rewriter' has no values".to_string());
125
1708
        }
126

            
127
1708
        parse_values(&self.rewriter)
128
1708
    }
129

            
130
1708
    pub fn configured_comprehension_expanders(&self) -> Result<Vec<QuantifiedExpander>, String> {
131
1708
        let values = if self.comprehension_expander.is_empty() {
132
            vec!["native".to_string()]
133
        } else {
134
1708
            self.comprehension_expander.clone()
135
        };
136

            
137
1708
        parse_values(&values)
138
1708
    }
139

            
140
1708
    pub fn configured_solvers(&self) -> Result<Vec<SolverFamily>, String> {
141
1708
        parse_values(&self.solver)
142
1708
    }
143

            
144
    pub fn uses_smt_solver(&self) -> bool {
145
        self.solver
146
            .iter()
147
            .any(|solver| solver == "smt" || solver.starts_with("smt-"))
148
    }
149
}