dsq_core/ops/
construct_ops.rs1use crate::error::Result;
2use crate::Value;
3
4use super::Operation;
5
6pub struct LiteralOperation {
8 pub value: Value,
9}
10
11impl LiteralOperation {
12 #[must_use]
13 pub fn new(value: Value) -> Self {
14 Self { value }
15 }
16}
17
18impl Operation for LiteralOperation {
19 fn apply(&self, _value: &Value) -> Result<Value> {
20 Ok(self.value.clone())
21 }
22
23 fn description(&self) -> String {
24 format!("literal: {:?}", self.value)
25 }
26}
27
28pub struct VariableOperation {
30 pub name: String,
31}
32
33impl VariableOperation {
34 #[must_use]
35 pub fn new(name: String) -> Self {
36 Self { name }
37 }
38}
39
40impl Operation for VariableOperation {
41 fn apply(&self, _value: &Value) -> Result<Value> {
42 Err(crate::error::Error::operation(format!(
44 "Variable '{}' not found",
45 self.name
46 )))
47 }
48
49 fn description(&self) -> String {
50 format!("variable: {}", self.name)
51 }
52}
53
54#[allow(clippy::type_complexity)]
56pub struct ObjectConstructOperation {
57 pub field_ops: Vec<(
58 Box<dyn Operation + Send + Sync>,
59 Option<Vec<Box<dyn Operation + Send + Sync>>>,
60 )>,
61}
62
63impl ObjectConstructOperation {
64 #[must_use]
65 #[allow(clippy::type_complexity)]
66 pub fn new(
67 field_ops: Vec<(
68 Box<dyn Operation + Send + Sync>,
69 Option<Vec<Box<dyn Operation + Send + Sync>>>,
70 )>,
71 ) -> Self {
72 Self { field_ops }
73 }
74}
75
76impl Operation for ObjectConstructOperation {
77 fn apply(&self, value: &Value) -> Result<Value> {
78 let mut obj = std::collections::HashMap::new();
79
80 for (key_op, value_op) in &self.field_ops {
81 let key_value = key_op.apply(value)?;
82 let Value::String(key) = key_value else {
83 return Err(crate::error::Error::operation(
84 "Object key must be a string",
85 ));
86 };
87
88 let field_value = if let Some(ref ops) = value_op {
89 let mut current = value.clone();
90 for op in ops {
91 current = op.apply(¤t)?;
92 }
93 current
94 } else {
95 value.field(&key)?
97 };
98
99 obj.insert(key, field_value);
100 }
101
102 Ok(Value::Object(obj))
103 }
104
105 fn description(&self) -> String {
106 "object construction".to_string()
107 }
108}
109
110pub struct ArrayConstructOperation {
112 pub element_ops: Vec<Box<dyn Operation + Send + Sync>>,
113}
114
115impl ArrayConstructOperation {
116 #[must_use]
117 pub fn new(element_ops: Vec<Box<dyn Operation + Send + Sync>>) -> Self {
118 Self { element_ops }
119 }
120}
121
122impl Operation for ArrayConstructOperation {
123 fn apply(&self, value: &Value) -> Result<Value> {
124 let mut arr = Vec::new();
125 for op in &self.element_ops {
126 arr.push(op.apply(value)?);
127 }
128 Ok(Value::Array(arr))
129 }
130
131 fn description(&self) -> String {
132 "array construction".to_string()
133 }
134}