helios_sof/sqlquery/
params.rs1use serde_json::Value;
4
5#[derive(Debug, Default, Clone)]
7pub struct SqlQueryRunParams {
8 pub format: Option<String>,
11 pub header: Option<bool>,
13 pub query_reference: Option<String>,
17 pub query_resource: Option<Value>,
19 pub parameters: Option<Value>,
23 pub source: Option<String>,
25 pub limit: Option<u32>,
30}
31
32pub fn extract_sqlquery_params_from_json(body: &Value) -> SqlQueryRunParams {
34 let mut out = SqlQueryRunParams::default();
35 if body.get("resourceType").and_then(|v| v.as_str()) != Some("Parameters") {
36 return out;
37 }
38 let Some(entries) = body.get("parameter").and_then(|p| p.as_array()) else {
39 return out;
40 };
41 for p in entries {
42 let Some(name) = p.get("name").and_then(|n| n.as_str()) else {
43 continue;
44 };
45 match name {
46 "_format" | "format" => {
47 if out.format.is_none() {
48 out.format = read_str(p, &["valueCode", "valueString"]);
49 }
50 }
51 "header" => {
52 if out.header.is_none() {
53 if let Some(b) = p.get("valueBoolean").and_then(|v| v.as_bool()) {
54 out.header = Some(b);
55 } else if let Some(s) = p.get("valueString").and_then(|v| v.as_str()) {
56 out.header = Some(s == "true" || s == "1");
57 }
58 }
59 }
60 "queryReference" => {
61 if out.query_reference.is_none() {
62 out.query_reference = read_reference(p);
63 }
64 }
65 "queryResource" => {
66 if out.query_resource.is_none() {
67 if let Some(r) = p.get("resource") {
68 out.query_resource = Some(r.clone());
69 }
70 }
71 }
72 "parameters" => {
73 if out.parameters.is_none() {
74 if let Some(r) = p.get("resource") {
75 out.parameters = Some(r.clone());
76 }
77 }
78 }
79 "source" => {
80 if out.source.is_none() {
81 out.source = read_str(p, &["valueString", "valueUri"]);
82 }
83 }
84 "_limit" => {
85 if out.limit.is_none() {
86 if let Some(n) = p.get("valueInteger").and_then(|v| v.as_u64()) {
87 out.limit = Some(n as u32);
88 } else if let Some(n) = p
89 .get("valuePositiveInt")
90 .or_else(|| p.get("valueUnsignedInt"))
91 .and_then(|v| v.as_u64())
92 {
93 out.limit = Some(n as u32);
94 }
95 }
96 }
97 _ => {}
98 }
99 }
100 out
101}
102
103fn read_str(p: &Value, keys: &[&str]) -> Option<String> {
104 for k in keys {
105 if let Some(s) = p.get(*k).and_then(|v| v.as_str()) {
106 return Some(s.to_string());
107 }
108 }
109 None
110}
111
112fn read_reference(p: &Value) -> Option<String> {
116 p.get("valueReference")
117 .and_then(|v| v.get("reference"))
118 .and_then(|v| v.as_str())
119 .map(str::to_string)
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125 use serde_json::json;
126
127 #[test]
128 fn extracts_format_and_header() {
129 let body = json!({
130 "resourceType": "Parameters",
131 "parameter": [
132 {"name": "_format", "valueCode": "csv"},
133 {"name": "header", "valueBoolean": false}
134 ]
135 });
136 let p = extract_sqlquery_params_from_json(&body);
137 assert_eq!(p.format.as_deref(), Some("csv"));
138 assert_eq!(p.header, Some(false));
139 }
140
141 #[test]
142 fn extracts_query_reference_and_resource() {
143 let body = json!({
144 "resourceType": "Parameters",
145 "parameter": [
146 {"name": "_format", "valueCode": "json"},
147 {"name": "queryReference", "valueReference": {"reference": "Library/foo"}},
148 {"name": "queryResource", "resource": {"resourceType": "Library"}}
149 ]
150 });
151 let p = extract_sqlquery_params_from_json(&body);
152 assert_eq!(p.query_reference.as_deref(), Some("Library/foo"));
153 assert!(p.query_resource.is_some());
154 }
155
156 #[test]
157 fn non_parameters_body_returns_default() {
158 let p = extract_sqlquery_params_from_json(&json!({"resourceType": "Bundle"}));
159 assert!(p.format.is_none());
160 }
161
162 #[test]
163 fn extracts_limit() {
164 let body = json!({
165 "resourceType": "Parameters",
166 "parameter": [
167 {"name": "_limit", "valueInteger": 50}
168 ]
169 });
170 let p = extract_sqlquery_params_from_json(&body);
171 assert_eq!(p.limit, Some(50));
172 }
173
174 #[test]
175 fn query_reference_only_reads_value_reference() {
176 let body = json!({
179 "resourceType": "Parameters",
180 "parameter": [
181 {"name": "_format", "valueCode": "json"},
182 {"name": "queryReference", "valueString": "Library/foo"}
183 ]
184 });
185 let p = extract_sqlquery_params_from_json(&body);
186 assert!(p.query_reference.is_none());
187 }
188}