1use crate::errors::err_invalid_hit_policy;
4use dsntk_common::DsntkError;
5use std::fmt;
6use std::fmt::Display;
7
8#[derive(Debug, Clone)]
10pub struct DecisionTable {
11 pub information_item_name: Option<String>,
13 pub input_clauses: Vec<InputClause>,
15 pub output_clauses: Vec<OutputClause>,
17 pub annotation_clauses: Vec<AnnotationClause>,
19 pub rules: Vec<DecisionRule>,
21 pub hit_policy: HitPolicy,
23 pub aggregation: Option<BuiltinAggregator>,
25 pub preferred_orientation: DecisionTableOrientation,
27 pub output_label: Option<String>,
29}
30
31impl DecisionTable {
32 #[allow(clippy::too_many_arguments)]
34 pub fn new(
35 information_item_name: Option<String>,
36 input_clauses: Vec<InputClause>,
37 output_clauses: Vec<OutputClause>,
38 annotation_clauses: Vec<AnnotationClause>,
39 rules: Vec<DecisionRule>,
40 hit_policy: HitPolicy,
41 aggregation: Option<BuiltinAggregator>,
42 preferred_orientation: DecisionTableOrientation,
43 output_label: Option<String>,
44 ) -> Self {
45 Self {
46 information_item_name,
47 input_clauses,
48 output_clauses,
49 annotation_clauses,
50 rules,
51 hit_policy,
52 aggregation,
53 preferred_orientation,
54 output_label,
55 }
56 }
57}
58
59#[derive(Debug, Clone, PartialEq, Eq)]
61pub struct InputClause {
62 pub input_expression: String,
64 pub allowed_input_values: Option<String>,
66}
67
68#[derive(Debug, Clone, PartialEq, Eq)]
70pub struct OutputClause {
71 pub output_component_name: Option<String>,
73 pub allowed_output_values: Option<String>,
75 pub default_output_value: Option<String>,
77}
78
79#[derive(Debug, Clone, PartialEq, Eq)]
81pub struct AnnotationClause {
82 pub name: String,
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
89pub struct DecisionRule {
90 pub input_entries: Vec<InputEntry>,
92 pub output_entries: Vec<OutputEntry>,
94 pub annotation_entries: Vec<AnnotationEntry>,
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
100pub struct InputEntry {
101 pub text: String,
103}
104
105#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct OutputEntry {
108 pub text: String,
110}
111
112#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct AnnotationEntry {
115 pub text: String,
117}
118
119#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
121pub enum HitPolicy {
122 Unique,
124 Any,
126 Priority,
128 First,
130 Collect(BuiltinAggregator),
132 OutputOrder,
134 RuleOrder,
136}
137
138impl HitPolicy {
139 pub fn aggregation(&self) -> Option<BuiltinAggregator> {
141 match self {
142 HitPolicy::Collect(aggregation) => Some(*aggregation),
143 _ => None,
144 }
145 }
146}
147
148impl Display for HitPolicy {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 write!(
152 f,
153 "{}",
154 match self {
155 HitPolicy::Unique => "U",
156 HitPolicy::Any => "A",
157 HitPolicy::Priority => "P",
158 HitPolicy::First => "F",
159 HitPolicy::RuleOrder => "R",
160 HitPolicy::OutputOrder => "O",
161 HitPolicy::Collect(aggregator) => match aggregator {
162 BuiltinAggregator::List => "C",
163 BuiltinAggregator::Sum => "C+",
164 BuiltinAggregator::Count => "C#",
165 BuiltinAggregator::Min => "C<",
166 BuiltinAggregator::Max => "C>",
167 },
168 }
169 )
170 }
171}
172
173impl TryFrom<&str> for HitPolicy {
174 type Error = DsntkError;
175 fn try_from(value: &str) -> dsntk_common::Result<Self, Self::Error> {
177 match value.trim() {
178 "U" => Ok(HitPolicy::Unique),
179 "A" => Ok(HitPolicy::Any),
180 "P" => Ok(HitPolicy::Priority),
181 "F" => Ok(HitPolicy::First),
182 "R" => Ok(HitPolicy::RuleOrder),
183 "O" => Ok(HitPolicy::OutputOrder),
184 "C" => Ok(HitPolicy::Collect(BuiltinAggregator::List)),
185 "C+" => Ok(HitPolicy::Collect(BuiltinAggregator::Sum)),
186 "C#" => Ok(HitPolicy::Collect(BuiltinAggregator::Count)),
187 "C<" => Ok(HitPolicy::Collect(BuiltinAggregator::Min)),
188 "C>" => Ok(HitPolicy::Collect(BuiltinAggregator::Max)),
189 other => Err(err_invalid_hit_policy(other)),
190 }
191 }
192}
193
194impl TryFrom<&String> for HitPolicy {
195 type Error = DsntkError;
196 fn try_from(value: &String) -> dsntk_common::Result<Self, Self::Error> {
198 Self::try_from(value.as_str())
199 }
200}
201
202#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
204pub enum BuiltinAggregator {
205 List,
207 Count,
209 Sum,
211 Min,
213 Max,
215}
216
217#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
219pub enum DecisionTableOrientation {
220 RulesAsRows,
222 RulesAsColumns,
224 CrossTable,
226}
227
228impl Display for DecisionTableOrientation {
229 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 write!(
232 f,
233 "{}",
234 match self {
235 DecisionTableOrientation::RulesAsRows => "rules-as-rows",
236 DecisionTableOrientation::RulesAsColumns => "rules-as-columns",
237 DecisionTableOrientation::CrossTable => "cross-table",
238 }
239 )
240 }
241}