Skip to main content

texform_transform/
config.rs

1//! User-facing transform configuration.
2
3use crate::finalize_ast::FinalizeAstConfig;
4use crate::flatten_groups::FlattenGroupsConfig;
5use crate::rewrite::plan::RuleSelection;
6use crate::rewrite::{NormalizationLevelSet, RuleKey};
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub enum Profile {
10    Authoring,
11    Faithful,
12    Corpus,
13    Equiv,
14}
15
16impl Profile {
17    pub const fn normalization_levels(self) -> NormalizationLevelSet {
18        match self {
19            Self::Authoring => NormalizationLevelSet::STANDARD,
20            Self::Faithful => NormalizationLevelSet::STANDARD.union(NormalizationLevelSet::EXPAND),
21            Self::Corpus => NormalizationLevelSet::STANDARD
22                .union(NormalizationLevelSet::EXPAND)
23                .union(NormalizationLevelSet::DROP),
24            Self::Equiv => NormalizationLevelSet::STANDARD
25                .union(NormalizationLevelSet::EXPAND)
26                .union(NormalizationLevelSet::DROP)
27                .union(NormalizationLevelSet::EQUIV),
28        }
29    }
30
31    pub const fn default_transform_config(self) -> TransformConfig {
32        match self {
33            Self::Authoring | Self::Faithful => TransformConfig {
34                rewrite_enabled: true,
35                lower_attributes_enabled: true,
36                finalize_ast: FinalizeAstConfig::ENABLED,
37                flatten_groups: FlattenGroupsConfig::STRICT,
38                max_iterations: 100,
39            },
40            Self::Corpus | Self::Equiv => TransformConfig {
41                rewrite_enabled: true,
42                lower_attributes_enabled: true,
43                finalize_ast: FinalizeAstConfig::ENABLED,
44                flatten_groups: FlattenGroupsConfig::STRUCTURAL_ONLY,
45                max_iterations: 100,
46            },
47        }
48    }
49}
50
51#[derive(Clone, Debug, PartialEq, Eq)]
52pub struct BuildConfig {
53    pub(crate) levels: NormalizationLevelSet,
54    pub(crate) selection: RuleSelection,
55    pub(crate) default_transform: TransformConfig,
56}
57
58impl BuildConfig {
59    pub fn profile(profile: Profile) -> Self {
60        Self {
61            levels: profile.normalization_levels(),
62            selection: RuleSelection::All,
63            default_transform: profile.default_transform_config(),
64        }
65    }
66
67    pub fn rewrite_levels(mut self, levels: NormalizationLevelSet) -> Self {
68        self.levels = levels;
69        self
70    }
71
72    pub fn disable_rule(mut self, key: RuleKey) -> Self {
73        match &mut self.selection {
74            RuleSelection::Except(keys) => {
75                if !keys.contains(&key) {
76                    keys.push(key);
77                }
78            }
79            _ => self.selection = RuleSelection::Except(vec![key]),
80        }
81        self
82    }
83
84    #[doc(hidden)]
85    pub fn only_rule_for_tests(mut self, key: RuleKey) -> Self {
86        self.selection = RuleSelection::Only(vec![key]);
87        self
88    }
89
90    #[doc(hidden)]
91    pub fn only_rules_for_tests(mut self, keys: Vec<RuleKey>) -> Self {
92        self.selection = RuleSelection::Only(keys);
93        self
94    }
95
96    pub(crate) fn default_transform(&self) -> TransformConfig {
97        self.default_transform
98    }
99}
100
101#[derive(Clone, Copy, Debug, PartialEq, Eq)]
102pub struct TransformConfig {
103    pub rewrite_enabled: bool,
104    pub lower_attributes_enabled: bool,
105    pub finalize_ast: FinalizeAstConfig,
106    pub flatten_groups: FlattenGroupsConfig,
107    pub max_iterations: usize,
108}
109
110#[derive(Clone, Debug, PartialEq, Eq)]
111pub struct NormalizeConfig {
112    pub parse: texform_core::parse::ParseConfig,
113    pub transform: TransformConfig,
114}
115
116#[cfg(test)]
117mod tests {
118    use super::*;
119    use crate::rewrite::NormalizationLevel;
120
121    #[test]
122    fn profiles_compile_as_const_and_carry_expected_levels() {
123        assert!(
124            Profile::Authoring
125                .normalization_levels()
126                .contains(NormalizationLevel::Standard)
127        );
128        assert!(
129            !Profile::Authoring
130                .normalization_levels()
131                .contains(NormalizationLevel::Expand)
132        );
133        assert!(
134            Profile::Faithful
135                .normalization_levels()
136                .contains(NormalizationLevel::Expand)
137        );
138        assert!(
139            !Profile::Faithful
140                .normalization_levels()
141                .contains(NormalizationLevel::Drop)
142        );
143        assert!(
144            Profile::Corpus
145                .normalization_levels()
146                .contains(NormalizationLevel::Drop)
147        );
148        assert!(
149            !Profile::Corpus
150                .normalization_levels()
151                .contains(NormalizationLevel::Equiv)
152        );
153        assert!(
154            Profile::Equiv
155                .normalization_levels()
156                .contains(NormalizationLevel::Equiv)
157        );
158        assert!(
159            Profile::Authoring
160                .default_transform_config()
161                .finalize_ast
162                .enabled
163        );
164        assert!(
165            Profile::Equiv
166                .default_transform_config()
167                .finalize_ast
168                .enabled
169        );
170        assert!(
171            Profile::Authoring
172                .default_transform_config()
173                .flatten_groups
174                .preserve_group_adjacent_to_command_like
175        );
176        assert!(
177            Profile::Faithful
178                .default_transform_config()
179                .flatten_groups
180                .preserve_group_adjacent_to_command_like
181        );
182        assert!(
183            !Profile::Corpus
184                .default_transform_config()
185                .flatten_groups
186                .preserve_group_adjacent_to_command_like
187        );
188        assert!(
189            !Profile::Equiv
190                .default_transform_config()
191                .flatten_groups
192                .preserve_group_adjacent_to_command_like
193        );
194        assert!(
195            Profile::Equiv
196                .default_transform_config()
197                .flatten_groups
198                .preserve_group_containing_infix
199        );
200    }
201}