1use serde::Deserialize;
2use serde_json::Value as JsonValue;
3
4#[derive(Debug, Deserialize, Clone)]
5#[serde(deny_unknown_fields)]
6pub struct RuleFile {
7 pub version: u8,
8 pub input: InputSpec,
9 #[serde(default)]
10 pub output: Option<OutputSpec>,
11 #[serde(default)]
12 pub record_when: Option<Expr>,
13 #[serde(default)]
14 pub mappings: Vec<Mapping>,
15 #[serde(default)]
16 pub steps: Option<Vec<V2RuleStep>>,
17 #[serde(default)]
18 pub finalize: Option<FinalizeSpec>,
19}
20
21#[derive(Debug, Deserialize, Clone)]
22#[serde(deny_unknown_fields)]
23pub struct OutputSpec {
24 pub name: Option<String>,
25}
26
27#[derive(Debug, Deserialize, Clone)]
28#[serde(deny_unknown_fields)]
29pub struct InputSpec {
30 pub format: InputFormat,
31 pub csv: Option<CsvInput>,
32 pub json: Option<JsonInput>,
33}
34
35#[derive(Debug, Deserialize, Clone, Copy)]
36#[serde(rename_all = "lowercase")]
37pub enum InputFormat {
38 Csv,
39 Json,
40}
41
42fn default_true() -> bool {
43 true
44}
45
46fn default_delimiter() -> String {
47 ",".to_string()
48}
49
50#[derive(Debug, Deserialize, Clone)]
51#[serde(deny_unknown_fields)]
52pub struct CsvInput {
53 #[serde(default = "default_true")]
54 pub has_header: bool,
55 #[serde(default = "default_delimiter")]
56 pub delimiter: String,
57 pub columns: Option<Vec<Column>>,
58}
59
60#[derive(Debug, Deserialize, Clone)]
61#[serde(deny_unknown_fields)]
62pub struct Column {
63 pub name: String,
64 #[serde(rename = "type")]
65 pub value_type: Option<String>,
66}
67
68#[derive(Debug, Deserialize, Clone)]
69#[serde(deny_unknown_fields)]
70pub struct JsonInput {
71 pub records_path: Option<String>,
72}
73
74#[derive(Debug, Deserialize, Clone)]
75#[serde(deny_unknown_fields)]
76pub struct Mapping {
77 pub target: String,
78 pub source: Option<String>,
79 pub value: Option<JsonValue>,
80 pub expr: Option<Expr>,
81 pub when: Option<Expr>,
82 #[serde(rename = "type")]
83 pub value_type: Option<String>,
84 #[serde(default)]
85 pub required: bool,
86 pub default: Option<JsonValue>,
87}
88
89#[derive(Debug, Deserialize, Clone)]
94#[serde(deny_unknown_fields)]
95pub struct V2RuleStep {
96 #[serde(default)]
97 pub name: Option<String>,
98 #[serde(default)]
99 pub mappings: Option<Vec<Mapping>>,
100 #[serde(default)]
101 pub record_when: Option<Expr>,
102 #[serde(default)]
103 pub asserts: Option<Vec<V2Assert>>,
104 #[serde(default)]
105 pub branch: Option<V2Branch>,
106}
107
108#[derive(Debug, Deserialize, Clone)]
109#[serde(deny_unknown_fields)]
110pub struct V2Assert {
111 pub when: Expr,
112 pub error: V2AssertError,
113}
114
115#[derive(Debug, Deserialize, Clone)]
116#[serde(deny_unknown_fields)]
117pub struct V2AssertError {
118 pub code: String,
119 pub message: String,
120}
121
122#[derive(Debug, Deserialize, Clone)]
123#[serde(deny_unknown_fields)]
124pub struct V2Branch {
125 pub when: Expr,
126 pub then: String,
127 #[serde(default)]
128 pub r#else: Option<String>,
129 #[serde(rename = "return", default)]
130 pub return_: bool,
131}
132
133#[derive(Debug, Deserialize, Clone)]
134#[serde(deny_unknown_fields)]
135pub struct FinalizeSpec {
136 #[serde(default)]
137 pub filter: Option<Expr>,
138 #[serde(default)]
139 pub sort: Option<FinalizeSort>,
140 #[serde(default)]
141 pub limit: Option<usize>,
142 #[serde(default)]
143 pub offset: Option<usize>,
144 #[serde(default)]
145 pub wrap: Option<JsonValue>,
146}
147
148#[derive(Debug, Deserialize, Clone)]
149#[serde(deny_unknown_fields)]
150pub struct FinalizeSort {
151 pub by: String,
152 #[serde(default = "default_sort_order")]
153 pub order: String,
154}
155
156fn default_sort_order() -> String {
157 "asc".to_string()
158}
159
160#[derive(Debug, Deserialize, Clone, PartialEq)]
161#[serde(untagged)]
162pub enum Expr {
163 Ref(ExprRef),
164 Op(ExprOp),
165 Chain(ExprChain),
166 Literal(JsonValue),
167}
168
169#[derive(Debug, Deserialize, Clone, PartialEq)]
170#[serde(deny_unknown_fields)]
171pub struct ExprRef {
172 #[serde(rename = "ref")]
173 pub ref_path: String,
174}
175
176#[derive(Debug, Deserialize, Clone, PartialEq)]
177#[serde(deny_unknown_fields)]
178pub struct ExprOp {
179 pub op: String,
180 #[serde(default)]
181 pub args: Vec<Expr>,
182}
183
184#[derive(Debug, Deserialize, Clone, PartialEq)]
185#[serde(deny_unknown_fields)]
186pub struct ExprChain {
187 pub chain: Vec<Expr>,
188}