dsq_shared/ops/
basic_ops.rs1use crate::value::Value;
6use crate::Result;
7use std::any::Any;
8
9use super::traits::Operation;
10
11pub struct IdentityOperation;
13
14impl Operation for IdentityOperation {
15 fn apply(&self, value: &Value) -> Result<Value> {
16 Ok(value.clone())
17 }
18
19 fn description(&self) -> String {
20 "identity".to_string()
21 }
22
23 fn as_any(&self) -> &dyn Any {
24 self
25 }
26}
27
28pub struct LiteralOperation {
32 pub value: Value,
34}
35
36impl LiteralOperation {
37 pub fn new(value: Value) -> Self {
39 Self { value }
40 }
41}
42
43impl Operation for LiteralOperation {
44 fn apply(&self, _value: &Value) -> Result<Value> {
45 Ok(self.value.clone())
46 }
47
48 fn description(&self) -> String {
49 format!("literal: {:?}", self.value)
50 }
51
52 fn as_any(&self) -> &dyn Any {
53 self
54 }
55}
56
57pub struct FieldAccessOperation {
59 pub fields: Vec<String>,
61}
62
63impl FieldAccessOperation {
64 pub fn new(field: String) -> Self {
66 Self {
67 fields: vec![field],
68 }
69 }
70
71 pub fn with_fields(fields: Vec<String>) -> Self {
73 Self { fields }
74 }
75}
76
77impl Operation for FieldAccessOperation {
78 fn apply(&self, value: &Value) -> Result<Value> {
79 let mut current = value.clone();
80 for field in &self.fields {
81 current = current.field(field)?;
82 }
83 Ok(current)
84 }
85
86 fn description(&self) -> String {
87 format!("field access: {}", self.fields.join("."))
88 }
89
90 fn as_any(&self) -> &dyn Any {
91 self
92 }
93}
94
95pub struct IndexOperation {
99 pub index_ops: Vec<Box<dyn Operation + Send + Sync>>,
101}
102
103impl IndexOperation {
104 pub fn new(index_ops: Vec<Box<dyn Operation + Send + Sync>>) -> Self {
106 Self { index_ops }
107 }
108}
109
110impl Operation for IndexOperation {
111 fn apply(&self, value: &Value) -> Result<Value> {
112 let mut current = value.clone();
113 for op in &self.index_ops {
114 let index_value = op.apply(¤t)?;
115 match index_value {
116 Value::Int(idx) => current = current.index(idx)?,
117 _ => return Err(crate::error::operation_error("Index must be an integer")),
118 }
119 }
120 Ok(current)
121 }
122
123 fn description(&self) -> String {
124 "array index".to_string()
125 }
126
127 fn as_any(&self) -> &dyn Any {
128 self
129 }
130}
131
132pub struct IterateOperation;
134
135impl Operation for IterateOperation {
136 fn apply(&self, value: &Value) -> Result<Value> {
137 match value {
138 Value::Array(arr) => Ok(Value::Array(arr.clone())),
139 Value::Object(obj) => {
140 let values: Vec<Value> = obj.values().cloned().collect();
141 Ok(Value::Array(values))
142 }
143 Value::DataFrame(df) => {
144 let mut rows = Vec::new();
146 for i in 0..df.height() {
147 let mut row_obj = std::collections::HashMap::new();
148 for col_name in df.get_column_names() {
149 if let Ok(series) = df.column(col_name) {
150 if let Ok(val) = series.get(i) {
151 let value = match val {
152 polars::prelude::AnyValue::Int64(i) => Value::Int(i),
153 polars::prelude::AnyValue::Float64(f) => Value::Float(f),
154 polars::prelude::AnyValue::String(s) => {
155 Value::String(s.to_string())
156 }
157 polars::prelude::AnyValue::Boolean(b) => Value::Bool(b),
158 _ => Value::Null,
159 };
160 row_obj.insert(col_name.to_string(), value);
161 }
162 }
163 }
164 rows.push(Value::Object(row_obj));
165 }
166 Ok(Value::Array(rows))
167 }
168 _ => Ok(value.clone()),
169 }
170 }
171
172 fn description(&self) -> String {
173 "iterate array/object".to_string()
174 }
175
176 fn as_any(&self) -> &dyn Any {
177 self
178 }
179}