1use crate::api::types::LemmaType;
4use crate::api::value::RuleResultValue;
5use crate::literals::Value;
6use crate::parsing::ast::{
7 ArithmeticComputation, CalendarPeriodUnit, ComparisonComputation, DateCalendarKind,
8 DateRelativeKind, DateTimeValue, MathematicalComputation, PrimitiveKind,
9};
10use crate::parsing::source::SourceType;
11use crate::planning::execution_plan::{
12 Show as DomainShow, ShowBranch as DomainShowBranch,
13 ShowConversionTarget as DomainConversionTarget, ShowData as DomainShowData,
14 ShowExpression as DomainShowExpression, ShowRule as DomainShowRule,
15 ShowVersion as DomainShowVersion,
16};
17use indexmap::IndexMap;
18use serde::{Deserialize, Serialize};
19
20#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21pub struct ShowData {
22 #[serde(rename = "type")]
23 pub lemma_type: LemmaType,
24 #[serde(skip_serializing_if = "Option::is_none", default)]
25 pub fill: Option<RuleResultValue>,
26 #[serde(skip_serializing_if = "Option::is_none", default)]
27 pub suggestion: Option<RuleResultValue>,
28 pub needed_by_rules: Vec<String>,
29}
30
31impl From<&DomainShowData> for ShowData {
32 fn from(data: &DomainShowData) -> Self {
33 Self {
34 lemma_type: LemmaType::from(&data.lemma_type),
35 fill: data.fill.as_ref().map(RuleResultValue::from),
36 suggestion: data.suggestion.as_ref().map(RuleResultValue::from),
37 needed_by_rules: data.needed_by_rules.clone(),
38 }
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43pub struct ShowVersion {
44 #[serde(skip_serializing_if = "Option::is_none", default)]
45 pub effective_from: Option<DateTimeValue>,
46 #[serde(skip_serializing_if = "Option::is_none", default)]
47 pub effective_to: Option<DateTimeValue>,
48}
49
50impl From<&DomainShowVersion> for ShowVersion {
51 fn from(version: &DomainShowVersion) -> Self {
52 Self {
53 effective_from: version.effective_from.clone(),
54 effective_to: version.effective_to.clone(),
55 }
56 }
57}
58
59#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
60#[serde(rename_all = "snake_case")]
61pub enum ShowConversionTarget {
62 Type(PrimitiveKind),
63 Unit { unit_name: String },
64}
65
66impl From<&DomainConversionTarget> for ShowConversionTarget {
67 fn from(target: &DomainConversionTarget) -> Self {
68 match target {
69 DomainConversionTarget::Type(kind) => Self::Type(*kind),
70 DomainConversionTarget::Unit { unit_name } => Self::Unit {
71 unit_name: unit_name.clone(),
72 },
73 }
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
79#[serde(tag = "type", rename_all = "snake_case")]
80pub enum ShowExpression {
81 Literal {
82 #[serde(flatten)]
83 value: Box<RuleResultValue>,
84 },
85 Data {
86 name: String,
87 },
88 Rule {
89 name: String,
90 },
91 And {
92 left: Box<ShowExpression>,
93 right: Box<ShowExpression>,
94 },
95 Not {
96 operand: Box<ShowExpression>,
97 },
98 Arithmetic {
99 op: ArithmeticComputation,
100 left: Box<ShowExpression>,
101 right: Box<ShowExpression>,
102 },
103 Comparison {
104 op: ComparisonComputation,
105 left: Box<ShowExpression>,
106 right: Box<ShowExpression>,
107 },
108 UnitConversion {
109 operand: Box<ShowExpression>,
110 target: ShowConversionTarget,
111 },
112 Math {
113 op: MathematicalComputation,
114 operand: Box<ShowExpression>,
115 },
116 Veto {
117 #[serde(skip_serializing_if = "Option::is_none", default)]
118 message: Option<String>,
119 },
120 Now,
121 DateRelative {
122 kind: DateRelativeKind,
123 operand: Box<ShowExpression>,
124 },
125 DateCalendar {
126 kind: DateCalendarKind,
127 unit: CalendarPeriodUnit,
128 operand: Box<ShowExpression>,
129 },
130 RangeLiteral {
131 from: Box<ShowExpression>,
132 to: Box<ShowExpression>,
133 },
134 PastFutureRange {
135 kind: DateRelativeKind,
136 operand: Box<ShowExpression>,
137 },
138 RangeContainment {
139 value: Box<ShowExpression>,
140 range: Box<ShowExpression>,
141 },
142 IsVeto {
143 operand: Box<ShowExpression>,
144 },
145}
146
147impl From<&DomainShowExpression> for ShowExpression {
148 fn from(expression: &DomainShowExpression) -> Self {
149 match expression {
150 DomainShowExpression::Literal(value) => Self::Literal {
151 value: Box::new(RuleResultValue::from(value.as_ref())),
152 },
153 DomainShowExpression::Data { name } => Self::Data { name: name.clone() },
154 DomainShowExpression::Rule { name } => Self::Rule { name: name.clone() },
155 DomainShowExpression::And { left, right } => Self::And {
156 left: Box::new(ShowExpression::from(left.as_ref())),
157 right: Box::new(ShowExpression::from(right.as_ref())),
158 },
159 DomainShowExpression::Not { operand } => Self::Not {
160 operand: Box::new(ShowExpression::from(operand.as_ref())),
161 },
162 DomainShowExpression::Arithmetic { op, left, right } => Self::Arithmetic {
163 op: op.clone(),
164 left: Box::new(ShowExpression::from(left.as_ref())),
165 right: Box::new(ShowExpression::from(right.as_ref())),
166 },
167 DomainShowExpression::Comparison { op, left, right } => Self::Comparison {
168 op: op.clone(),
169 left: Box::new(ShowExpression::from(left.as_ref())),
170 right: Box::new(ShowExpression::from(right.as_ref())),
171 },
172 DomainShowExpression::UnitConversion { operand, target } => Self::UnitConversion {
173 operand: Box::new(ShowExpression::from(operand.as_ref())),
174 target: ShowConversionTarget::from(target),
175 },
176 DomainShowExpression::Math { op, operand } => Self::Math {
177 op: op.clone(),
178 operand: Box::new(ShowExpression::from(operand.as_ref())),
179 },
180 DomainShowExpression::Veto { message } => Self::Veto {
181 message: message.clone(),
182 },
183 DomainShowExpression::Now => Self::Now,
184 DomainShowExpression::DateRelative { kind, operand } => Self::DateRelative {
185 kind: *kind,
186 operand: Box::new(ShowExpression::from(operand.as_ref())),
187 },
188 DomainShowExpression::DateCalendar {
189 kind,
190 unit,
191 operand,
192 } => Self::DateCalendar {
193 kind: *kind,
194 unit: *unit,
195 operand: Box::new(ShowExpression::from(operand.as_ref())),
196 },
197 DomainShowExpression::RangeLiteral { from, to } => Self::RangeLiteral {
198 from: Box::new(ShowExpression::from(from.as_ref())),
199 to: Box::new(ShowExpression::from(to.as_ref())),
200 },
201 DomainShowExpression::PastFutureRange { kind, operand } => Self::PastFutureRange {
202 kind: *kind,
203 operand: Box::new(ShowExpression::from(operand.as_ref())),
204 },
205 DomainShowExpression::RangeContainment { value, range } => Self::RangeContainment {
206 value: Box::new(ShowExpression::from(value.as_ref())),
207 range: Box::new(ShowExpression::from(range.as_ref())),
208 },
209 DomainShowExpression::IsVeto { operand } => Self::IsVeto {
210 operand: Box::new(ShowExpression::from(operand.as_ref())),
211 },
212 }
213 }
214}
215
216#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
217pub struct ShowBranch {
218 #[serde(skip_serializing_if = "Option::is_none", default)]
219 pub condition: Option<ShowExpression>,
220 pub result: ShowExpression,
221}
222
223impl From<&DomainShowBranch> for ShowBranch {
224 fn from(branch: &DomainShowBranch) -> Self {
225 Self {
226 condition: branch.condition.as_ref().map(ShowExpression::from),
227 result: ShowExpression::from(&branch.result),
228 }
229 }
230}
231
232#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
233pub struct ShowRule {
234 #[serde(rename = "type")]
235 pub lemma_type: LemmaType,
236 pub branches: Vec<ShowBranch>,
237 pub depends_on_rules: Vec<String>,
238}
239
240impl From<&DomainShowRule> for ShowRule {
241 fn from(rule: &DomainShowRule) -> Self {
242 Self {
243 lemma_type: LemmaType::from(&rule.lemma_type),
244 branches: rule.branches.iter().map(ShowBranch::from).collect(),
245 depends_on_rules: rule.depends_on_rules.clone(),
246 }
247 }
248}
249
250#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
251pub struct Show {
252 pub spec: String,
253 #[serde(skip_serializing_if = "Option::is_none", default)]
254 pub commentary: Option<String>,
255 #[serde(skip_serializing_if = "Option::is_none", default)]
256 pub effective_from: Option<DateTimeValue>,
257 #[serde(skip_serializing_if = "Option::is_none", default)]
258 pub effective_to: Option<DateTimeValue>,
259 #[serde(skip_serializing_if = "Vec::is_empty", default)]
260 pub versions: Vec<ShowVersion>,
261 pub start_line: usize,
262 #[serde(skip_serializing_if = "Option::is_none", default)]
263 pub source_type: Option<SourceType>,
264 pub data: IndexMap<String, ShowData>,
265 pub rules: IndexMap<String, ShowRule>,
266 pub meta: IndexMap<String, Value>,
267}
268
269impl From<&DomainShow> for Show {
270 fn from(show: &DomainShow) -> Self {
271 Self {
272 spec: show.spec.clone(),
273 commentary: show.commentary.clone(),
274 effective_from: show.effective_from.clone(),
275 effective_to: show.effective_to.clone(),
276 versions: show.versions.iter().map(ShowVersion::from).collect(),
277 start_line: show.start_line,
278 source_type: show.source_type.clone(),
279 data: show
280 .data
281 .iter()
282 .map(|(name, data)| (name.clone(), ShowData::from(data)))
283 .collect(),
284 rules: show
285 .rules
286 .iter()
287 .map(|(name, rule)| (name.clone(), ShowRule::from(rule)))
288 .collect(),
289 meta: show.meta.clone(),
290 }
291 }
292}