vantage_api_client/rest/
operation.rs1use ciborium::Value as CborValue;
12use vantage_expressions::Expression;
13use vantage_expressions::traits::expressive::ExpressiveEnum;
14
15pub fn eq_condition(field: &str, value: impl Into<CborValue>) -> Expression<CborValue> {
22 Expression::new(
23 "{} = {}",
24 vec![
25 ExpressiveEnum::Nested(Expression::new(field.to_string(), vec![])),
26 ExpressiveEnum::Nested(Expression::new(
27 "{}",
28 vec![ExpressiveEnum::Scalar(value.into())],
29 )),
30 ],
31 )
32}
33
34pub(crate) fn condition_to_query_param(cond: &Expression<CborValue>) -> Option<(String, String)> {
39 if cond.template != "{} = {}" || cond.parameters.len() != 2 {
40 return None;
41 }
42
43 let field = match &cond.parameters[0] {
44 ExpressiveEnum::Nested(e) if e.parameters.is_empty() => e.template.clone(),
45 _ => return None,
46 };
47
48 let value = match &cond.parameters[1] {
49 ExpressiveEnum::Nested(e) if e.template == "{}" && e.parameters.len() == 1 => {
50 match &e.parameters[0] {
51 ExpressiveEnum::Scalar(v) => cbor_to_query_string(v)?,
52 _ => return None,
53 }
54 }
55 ExpressiveEnum::Scalar(v) => cbor_to_query_string(v)?,
56 _ => return None,
57 };
58
59 Some((field, value))
60}
61
62pub(crate) fn cbor_to_query_string(v: &CborValue) -> Option<String> {
67 match v {
68 CborValue::Bool(b) => Some(b.to_string()),
69 CborValue::Integer(i) => Some(i128::from(*i).to_string()),
70 CborValue::Float(f) => Some(f.to_string()),
71 CborValue::Text(s) => Some(s.clone()),
72 CborValue::Null | CborValue::Array(_) | CborValue::Map(_) | CborValue::Bytes(_) => None,
73 _ => None,
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn eq_condition_round_trips_int() {
83 let cond = eq_condition("userId", 1i64);
84 let pair = condition_to_query_param(&cond).expect("eq parses");
85 assert_eq!(pair, ("userId".into(), "1".into()));
86 }
87
88 #[test]
89 fn eq_condition_round_trips_string() {
90 let cond = eq_condition("name", "Alice");
91 let pair = condition_to_query_param(&cond).expect("eq parses");
92 assert_eq!(pair, ("name".into(), "Alice".into()));
93 }
94
95 #[test]
96 fn eq_condition_round_trips_bool() {
97 let cond = eq_condition("completed", true);
98 let pair = condition_to_query_param(&cond).expect("eq parses");
99 assert_eq!(pair, ("completed".into(), "true".into()));
100 }
101
102 #[test]
103 fn raw_expression_with_unknown_template_returns_none() {
104 let cond = Expression::<CborValue>::new("CUSTOM SQL", vec![]);
105 assert!(condition_to_query_param(&cond).is_none());
106 }
107
108 #[test]
109 fn array_value_returns_none() {
110 let cond = eq_condition("tags", vec![CborValue::Text("a".into())]);
111 assert!(condition_to_query_param(&cond).is_none());
112 }
113}