1use crate::evaluation::variable_value::VariableValue;
16use async_trait::async_trait;
17use drasi_query_ast::ast;
18
19use crate::evaluation::functions::ScalarFunction;
20use crate::evaluation::{ExpressionEvaluationContext, FunctionError, FunctionEvaluationError};
21
22#[derive(Debug, PartialEq)]
23pub struct ToUpper {}
24
25#[async_trait]
26impl ScalarFunction for ToUpper {
27 async fn call(
28 &self,
29 _context: &ExpressionEvaluationContext,
30 expression: &ast::FunctionExpression,
31 args: Vec<VariableValue>,
32 ) -> Result<VariableValue, FunctionError> {
33 if args.len() != 1 {
34 return Err(FunctionError {
35 function_name: expression.name.to_string(),
36 error: FunctionEvaluationError::InvalidArgumentCount,
37 });
38 }
39 match &args[0] {
40 VariableValue::String(s) => Ok(VariableValue::String(s.to_uppercase())),
41 VariableValue::Null => Ok(VariableValue::Null),
42 _ => Err(FunctionError {
43 function_name: expression.name.to_string(),
44 error: FunctionEvaluationError::InvalidArgument(0),
45 }),
46 }
47 }
48}
49
50#[derive(Debug)]
51pub struct ToLower {}
52
53#[async_trait]
54impl ScalarFunction for ToLower {
55 async fn call(
56 &self,
57 _context: &ExpressionEvaluationContext,
58 expression: &ast::FunctionExpression,
59 args: Vec<VariableValue>,
60 ) -> Result<VariableValue, FunctionError> {
61 if args.len() != 1 {
62 return Err(FunctionError {
63 function_name: expression.name.to_string(),
64 error: FunctionEvaluationError::InvalidArgumentCount,
65 });
66 }
67 match &args[0] {
68 VariableValue::String(s) => Ok(VariableValue::String(s.to_lowercase())),
69 VariableValue::Null => Ok(VariableValue::Null),
70 _ => Err(FunctionError {
71 function_name: expression.name.to_string(),
72 error: FunctionEvaluationError::InvalidArgument(0),
73 }),
74 }
75 }
76}
77
78#[derive(Debug)]
79pub struct Trim {}
80
81#[async_trait]
82impl ScalarFunction for Trim {
83 async fn call(
84 &self,
85 _context: &ExpressionEvaluationContext,
86 expression: &ast::FunctionExpression,
87 args: Vec<VariableValue>,
88 ) -> Result<VariableValue, FunctionError> {
89 if args.len() != 1 {
90 return Err(FunctionError {
91 function_name: expression.name.to_string(),
92 error: FunctionEvaluationError::InvalidArgumentCount,
93 });
94 }
95 match &args[0] {
96 VariableValue::String(s) => Ok(VariableValue::String(s.trim().to_string())),
97 VariableValue::Null => Ok(VariableValue::Null),
98 _ => Err(FunctionError {
99 function_name: expression.name.to_string(),
100 error: FunctionEvaluationError::InvalidArgument(0),
101 }),
102 }
103 }
104}
105
106#[derive(Debug)]
107pub struct LTrim {}
108
109#[async_trait]
110impl ScalarFunction for LTrim {
111 async fn call(
112 &self,
113 _context: &ExpressionEvaluationContext,
114 expression: &ast::FunctionExpression,
115 args: Vec<VariableValue>,
116 ) -> Result<VariableValue, FunctionError> {
117 if args.len() != 1 {
118 return Err(FunctionError {
119 function_name: expression.name.to_string(),
120 error: FunctionEvaluationError::InvalidArgumentCount,
121 });
122 }
123 match &args[0] {
124 VariableValue::String(s) => Ok(VariableValue::String(s.trim_start().to_string())),
125 VariableValue::Null => Ok(VariableValue::Null),
126 _ => Err(FunctionError {
127 function_name: expression.name.to_string(),
128 error: FunctionEvaluationError::InvalidArgument(0),
129 }),
130 }
131 }
132}
133
134#[derive(Debug)]
135pub struct RTrim {}
136
137#[async_trait]
138impl ScalarFunction for RTrim {
139 async fn call(
140 &self,
141 _context: &ExpressionEvaluationContext,
142 expression: &ast::FunctionExpression,
143 args: Vec<VariableValue>,
144 ) -> Result<VariableValue, FunctionError> {
145 if args.len() != 1 {
146 return Err(FunctionError {
147 function_name: expression.name.to_string(),
148 error: FunctionEvaluationError::InvalidArgumentCount,
149 });
150 }
151 match &args[0] {
152 VariableValue::String(s) => Ok(VariableValue::String(s.trim_end().to_string())),
153 VariableValue::Null => Ok(VariableValue::Null),
154 _ => Err(FunctionError {
155 function_name: expression.name.to_string(),
156 error: FunctionEvaluationError::InvalidArgument(0),
157 }),
158 }
159 }
160}
161
162#[derive(Debug)]
163pub struct Reverse {}
164
165#[async_trait]
166impl ScalarFunction for Reverse {
167 async fn call(
168 &self,
169 _context: &ExpressionEvaluationContext,
170 expression: &ast::FunctionExpression,
171 args: Vec<VariableValue>,
172 ) -> Result<VariableValue, FunctionError> {
173 if args.len() != 1 {
174 return Err(FunctionError {
175 function_name: expression.name.to_string(),
176 error: FunctionEvaluationError::InvalidArgumentCount,
177 });
178 }
179 match &args[0] {
180 VariableValue::String(s) => Ok(VariableValue::String(s.chars().rev().collect())),
181 VariableValue::List(l) => {
182 let mut l = l.clone();
183 l.reverse();
184 Ok(VariableValue::List(l))
185 }
186 VariableValue::Null => Ok(VariableValue::Null),
187 _ => Err(FunctionError {
188 function_name: expression.name.to_string(),
189 error: FunctionEvaluationError::InvalidArgument(0),
190 }),
191 }
192 }
193}
194
195#[derive(Debug)]
196pub struct Left {}
197
198#[async_trait]
199impl ScalarFunction for Left {
200 async fn call(
201 &self,
202 _context: &ExpressionEvaluationContext,
203 expression: &ast::FunctionExpression,
204 args: Vec<VariableValue>,
205 ) -> Result<VariableValue, FunctionError> {
206 if args.len() != 2 {
207 return Err(FunctionError {
208 function_name: expression.name.to_string(),
209 error: FunctionEvaluationError::InvalidArgumentCount,
210 });
211 }
212 match (&args[0], &args[1]) {
213 (VariableValue::Null, VariableValue::Integer(_length)) => Ok(VariableValue::Null),
214 (VariableValue::Null, VariableValue::Null) => Ok(VariableValue::Null),
215 (VariableValue::String(original), VariableValue::Integer(length)) => {
216 let len = match length.as_i64() {
217 Some(l) => {
218 if l <= 0 {
219 return Err(FunctionError {
220 function_name: expression.name.to_string(),
221 error: FunctionEvaluationError::OverflowError,
222 });
223 }
224 l as usize
225 }
226 None => {
227 return Err(FunctionError {
228 function_name: expression.name.to_string(),
229 error: FunctionEvaluationError::InvalidArgument(1),
230 })
231 }
232 };
233 if len > original.len() {
234 return Ok(VariableValue::String(original.to_string()));
235 }
236 let result = original.chars().take(len).collect::<String>();
237 Ok(VariableValue::String(result))
238 }
239 (VariableValue::String(_original), _) => {
240 return Err(FunctionError {
241 function_name: expression.name.to_string(),
242 error: FunctionEvaluationError::InvalidArgument(1),
243 })
244 }
245 _ => Err(FunctionError {
246 function_name: expression.name.to_string(),
247 error: FunctionEvaluationError::InvalidArgument(0),
248 }),
249 }
250 }
251}
252
253#[derive(Debug)]
254pub struct Right {}
255
256#[async_trait]
257impl ScalarFunction for Right {
258 async fn call(
259 &self,
260 _context: &ExpressionEvaluationContext,
261 expression: &ast::FunctionExpression,
262 args: Vec<VariableValue>,
263 ) -> Result<VariableValue, FunctionError> {
264 if args.len() != 2 {
265 return Err(FunctionError {
266 function_name: expression.name.to_string(),
267 error: FunctionEvaluationError::InvalidArgumentCount,
268 });
269 }
270 match (&args[0], &args[1]) {
271 (VariableValue::Null, VariableValue::Integer(_length)) => Ok(VariableValue::Null),
272 (VariableValue::Null, VariableValue::Null) => Ok(VariableValue::Null),
273 (VariableValue::String(original), VariableValue::Integer(length)) => {
274 let len = match length.as_i64() {
275 Some(l) => {
276 if l <= 0 {
277 return Err(FunctionError {
278 function_name: expression.name.to_string(),
279 error: FunctionEvaluationError::OverflowError,
280 });
281 }
282 l as usize
283 }
284 None => {
285 return Err(FunctionError {
286 function_name: expression.name.to_string(),
287 error: FunctionEvaluationError::InvalidArgument(1),
288 })
289 }
290 };
291 if len > original.len() {
292 return Ok(VariableValue::String(original.to_string()));
293 }
294 let start_index = original.len() - len;
295 let result = original[start_index..].to_string();
296 Ok(VariableValue::String(result))
297 }
298 (VariableValue::String(_), _) => {
299 return Err(FunctionError {
300 function_name: expression.name.to_string(),
301 error: FunctionEvaluationError::InvalidArgument(1),
302 })
303 }
304 _ => Err(FunctionError {
305 function_name: expression.name.to_string(),
306 error: FunctionEvaluationError::InvalidArgument(0),
307 }),
308 }
309 }
310}
311
312#[derive(Debug)]
313pub struct Replace {}
314
315#[async_trait]
316impl ScalarFunction for Replace {
317 async fn call(
318 &self,
319 _context: &ExpressionEvaluationContext,
320 expression: &ast::FunctionExpression,
321 args: Vec<VariableValue>,
322 ) -> Result<VariableValue, FunctionError> {
323 if args.len() != 3 {
324 return Err(FunctionError {
325 function_name: expression.name.to_string(),
326 error: FunctionEvaluationError::InvalidArgumentCount,
327 });
328 }
329 match (&args[0], &args[1], &args[2]) {
330 (
331 VariableValue::String(original),
332 VariableValue::String(search),
333 VariableValue::String(replace),
334 ) => {
335 if search.is_empty() {
336 return Ok(VariableValue::String(original.to_string()));
337 }
338 let result = original.replace(search, replace);
339 return Ok(VariableValue::String(result));
340 }
341
342 (VariableValue::Null, _, _) => Ok(VariableValue::Null),
343 (_, VariableValue::Null, _) => Ok(VariableValue::Null),
344 (_, _, VariableValue::Null) => Ok(VariableValue::Null),
345 (VariableValue::String(_), VariableValue::String(_), _) => Err(FunctionError {
346 function_name: expression.name.to_string(),
347 error: FunctionEvaluationError::InvalidArgument(2),
348 }),
349 (_, VariableValue::String(_), _) => Err(FunctionError {
350 function_name: expression.name.to_string(),
351 error: FunctionEvaluationError::InvalidArgument(0),
352 }),
353 _ => Err(FunctionError {
354 function_name: expression.name.to_string(),
355 error: FunctionEvaluationError::InvalidArgument(0),
356 }),
357 }
358 }
359}
360
361#[derive(Debug)]
362pub struct Split {}
363
364#[async_trait]
365impl ScalarFunction for Split {
366 async fn call(
367 &self,
368 _context: &ExpressionEvaluationContext,
369 expression: &ast::FunctionExpression,
370 args: Vec<VariableValue>,
371 ) -> Result<VariableValue, FunctionError> {
372 if args.len() != 2 {
373 return Err(FunctionError {
374 function_name: expression.name.to_string(),
375 error: FunctionEvaluationError::InvalidArgumentCount,
376 });
377 }
378 match (&args[0], &args[1]) {
379 (VariableValue::Null, _) => Ok(VariableValue::Null),
380 (_, VariableValue::Null) => Ok(VariableValue::Null),
381 (VariableValue::String(original), VariableValue::String(separator)) => {
382 if separator.is_empty() {
383 return Err(FunctionError {
384 function_name: expression.name.to_string(),
385 error: FunctionEvaluationError::InvalidArgument(1),
386 });
387 }
388 let result = original
389 .split(separator)
390 .map(|s| VariableValue::String(s.to_string()))
391 .collect::<Vec<VariableValue>>();
392 return Ok(VariableValue::List(result));
393 }
394 (VariableValue::String(original), VariableValue::List(delimiters)) => {
395 let mut delimiters_vector = Vec::new();
397 let mut result = Vec::new();
398 let mut current_word = String::new();
399
400 for delimiter in delimiters {
401 match delimiter {
402 VariableValue::String(s) => delimiters_vector.push(s),
403 _ => {
404 return Err(FunctionError {
405 function_name: expression.name.to_string(),
406 error: FunctionEvaluationError::InvalidArgument(1),
407 })
408 }
409 }
410 }
411 for c in original.chars() {
412 if delimiters_vector.iter().any(|d| d.contains(c)) {
413 if !current_word.is_empty() {
414 result.push(VariableValue::String(current_word.clone()));
415 current_word.clear();
416 }
417 } else {
418 current_word.push(c);
419 }
420 }
421 if !current_word.is_empty() {
422 result.push(VariableValue::String(current_word));
423 }
424 return Ok(VariableValue::List(result));
425 }
426 _ => Err(FunctionError {
427 function_name: expression.name.to_string(),
428 error: FunctionEvaluationError::InvalidArgument(0),
429 }),
430 }
431 }
432}
433
434#[derive(Debug)]
435pub struct Substring {}
436
437#[async_trait]
438impl ScalarFunction for Substring {
439 async fn call(
440 &self,
441 _context: &ExpressionEvaluationContext,
442 expression: &ast::FunctionExpression,
443 args: Vec<VariableValue>,
444 ) -> Result<VariableValue, FunctionError> {
445 if args.len() < 2 || args.len() > 3 {
446 return Err(FunctionError {
447 function_name: expression.name.to_string(),
448 error: FunctionEvaluationError::InvalidArgumentCount,
449 });
450 }
451 match (&args[0], &args[1], &args.get(2)) {
452 (VariableValue::Null, _, _) => Ok(VariableValue::Null),
453 (_, VariableValue::Null, _) => Err(FunctionError {
454 function_name: expression.name.to_string(),
455 error: FunctionEvaluationError::InvalidArgument(1),
456 }),
457 (_, _, Some(VariableValue::Null)) => Err(FunctionError {
458 function_name: expression.name.to_string(),
459 error: FunctionEvaluationError::InvalidArgument(2),
460 }),
461 (VariableValue::String(original), VariableValue::Integer(start), None) => {
462 let start_index = match start.as_i64() {
464 Some(s) => {
465 if s < 0 {
466 return Err(FunctionError {
467 function_name: expression.name.to_string(),
468 error: FunctionEvaluationError::InvalidType {
469 expected: "positive integer".to_string(),
470 },
471 });
472 }
473 s as usize
474 }
475 None => {
476 return Err(FunctionError {
477 function_name: expression.name.to_string(),
478 error: FunctionEvaluationError::InvalidArgument(1),
479 })
480 }
481 };
482 if start_index > original.len() {
483 return Err(FunctionError {
484 function_name: expression.name.to_string(),
485 error: FunctionEvaluationError::InvalidArgument(1),
486 });
487 }
488 return Ok(VariableValue::String(original[start_index..].to_string()));
489 }
490 (VariableValue::String(_), _, None) => {
491 return Err(FunctionError {
492 function_name: expression.name.to_string(),
493 error: FunctionEvaluationError::InvalidArgument(1),
494 });
495 }
496 (
497 VariableValue::String(original),
498 VariableValue::Integer(start),
499 Some(VariableValue::Integer(length)),
500 ) => {
501 let start_index = match start.as_i64() {
502 Some(s) => {
503 if s < 0 {
504 return Err(FunctionError {
505 function_name: expression.name.to_string(),
506 error: FunctionEvaluationError::InvalidType {
507 expected: "positive integer".to_string(),
508 },
509 });
510 }
511 s as usize
512 }
513 None => {
514 return Err(FunctionError {
515 function_name: expression.name.to_string(),
516 error: FunctionEvaluationError::InvalidArgument(1),
517 })
518 }
519 };
520
521 let len = match length.as_i64() {
522 Some(l) => {
523 if l < 0 {
524 return Err(FunctionError {
525 function_name: expression.name.to_string(),
526 error: FunctionEvaluationError::InvalidType {
527 expected: "positive integer".to_string(),
528 },
529 });
530 }
531 l as usize
532 }
533 None => {
534 return Err(FunctionError {
535 function_name: expression.name.to_string(),
536 error: FunctionEvaluationError::InvalidArgument(2),
537 })
538 }
539 };
540 if start_index > original.len() || start_index + len - start_index > original.len()
541 {
542 return Err(FunctionError {
543 function_name: expression.name.to_string(),
544 error: FunctionEvaluationError::InvalidType {
545 expected: "Valid index or length".to_string(),
546 },
547 });
548 }
549 return Ok(VariableValue::String(
550 original[start_index..start_index + len].to_string(),
551 ));
552 }
553 (VariableValue::String(_), VariableValue::Integer(_), _) => {
554 return Err(FunctionError {
555 function_name: expression.name.to_string(),
556 error: FunctionEvaluationError::InvalidArgument(2),
557 });
558 }
559 _ => {
560 return Err(FunctionError {
561 function_name: expression.name.to_string(),
562 error: FunctionEvaluationError::InvalidArgument(0),
563 })
564 }
565 }
566 }
567}
568
569pub struct ToString {}
570
571#[async_trait]
572impl ScalarFunction for ToString {
573 async fn call(
574 &self,
575 _context: &ExpressionEvaluationContext,
576 expression: &ast::FunctionExpression,
577 args: Vec<VariableValue>,
578 ) -> Result<VariableValue, FunctionError> {
579 if args.len() != 1 {
580 return Err(FunctionError {
581 function_name: expression.name.to_string(),
582 error: FunctionEvaluationError::InvalidArgumentCount,
583 });
584 }
585 match &args[0] {
586 VariableValue::Integer(n) => return Ok(VariableValue::String(n.to_string())),
587 VariableValue::Float(n) => return Ok(VariableValue::String(n.to_string())),
588 VariableValue::String(s) => return Ok(VariableValue::String(s.to_string())),
589 VariableValue::Bool(b) => return Ok(VariableValue::String(b.to_string())),
590 VariableValue::List(a) => {
591 let mut result = String::new();
592 result.push('[');
593 for v in a {
594 result.push_str(&v.to_string());
595 result.push_str(", ");
596 }
597 result.truncate(result.len() - 2);
598 result.push(']');
599 return Ok(VariableValue::String(result));
600 }
601 VariableValue::Null => return Ok(VariableValue::Null),
602 _ => {
603 return Err(FunctionError {
604 function_name: expression.name.to_string(),
605 error: FunctionEvaluationError::InvalidArgument(0),
606 })
607 }
608 }
609 }
610}
611
612pub struct ToStringOrNull {}
613
614#[async_trait]
615impl ScalarFunction for ToStringOrNull {
616 async fn call(
617 &self,
618 _context: &ExpressionEvaluationContext,
619 expression: &ast::FunctionExpression,
620 args: Vec<VariableValue>,
621 ) -> Result<VariableValue, FunctionError> {
622 if args.len() != 1 {
623 return Err(FunctionError {
624 function_name: expression.name.to_string(),
625 error: FunctionEvaluationError::InvalidArgumentCount,
626 });
627 }
628 match &args[0] {
629 VariableValue::Null => return Ok(VariableValue::Null),
630 VariableValue::Integer(n) => return Ok(VariableValue::String(n.to_string())),
631 VariableValue::Float(n) => return Ok(VariableValue::String(n.to_string())),
632 VariableValue::String(s) => return Ok(VariableValue::String(s.to_string())),
633 VariableValue::List(a) => {
634 let mut result = String::new();
635 result.push('[');
636 for v in a {
637 result.push_str(&v.to_string());
638 result.push_str(", ");
639 }
640 result.truncate(result.len() - 2);
641 result.push(']');
642 return Ok(VariableValue::String(result));
643 }
644 VariableValue::Object(_o) => {
645 return Ok(VariableValue::Null);
647 }
648 _ => {
649 return Err(FunctionError {
650 function_name: expression.name.to_string(),
651 error: FunctionEvaluationError::InvalidArgument(0),
652 })
653 }
654 }
655 }
656}
657
658#[derive(Debug)]
659pub struct RandomUUID {}
660
661#[async_trait]
662impl ScalarFunction for RandomUUID {
663 async fn call(
664 &self,
665 _context: &ExpressionEvaluationContext,
666 expression: &ast::FunctionExpression,
667 args: Vec<VariableValue>,
668 ) -> Result<VariableValue, FunctionError> {
669 if !args.is_empty() {
670 return Err(FunctionError {
671 function_name: expression.name.to_string(),
672 error: FunctionEvaluationError::InvalidArgumentCount,
673 });
674 }
675 Ok(VariableValue::String(uuid::Uuid::new_v4().to_string()))
676 }
677}