1use crate::ast::*;
9use crate::parser::{parse, ParseError};
10
11use std::collections::HashMap;
12use std::fmt;
13
14#[derive(Debug, Clone, PartialEq)]
20pub enum RuntimeValue {
21 Integer(i64),
22 Float(f64),
23 String(String),
24 Boolean(bool),
25 Null,
26}
27
28#[derive(Debug, Clone, PartialEq)]
30pub enum EvalError {
31
32 EvalParseError(String),
34
35 UnboundVariable {
37 name: String
38 },
39
40 TypeError {
42 operation: String,
43 expected: String,
44 actual: String,
45 context: String,
46 },
47
48 NullInOperation {
50 operation: String,
51 context: String,
52 },
53
54 DivisionByZero {
56 expression: String,
57 },
58
59 InvalidLiteral {
61 literal: String,
62 literal_type: String,
63 error: String,
64 },
65}
66
67impl fmt::Display for EvalError {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 match self {
70 EvalError::EvalParseError(msg) => write!(f, "Parse error: {}", msg),
71 EvalError::UnboundVariable { name } => {
72 write!(f, "Unbound variable '{}' - not found in value map", name)
73 }
74 EvalError::TypeError { operation, expected, actual, context } => {
75 write!(f, "Type error in {}: expected {}, got {} (context: {})",
76 operation, expected, actual, context)
77 }
78 EvalError::NullInOperation { operation, context } => {
79 write!(f, "NULL value in {} operation (context: {}). NULL is only allowed in IS NULL/IS NOT NULL",
80 operation, context)
81 }
82 EvalError::DivisionByZero { expression } => {
83 write!(f, "Division by zero in expression: {}", expression)
84 }
85 EvalError::InvalidLiteral { literal, literal_type, error } => {
86 write!(f, "Invalid {} literal '{}': {}", literal_type, literal, error)
87 }
88 }
89 }
90}
91
92impl std::error::Error for EvalError {}
93
94impl From<String> for EvalError {
95 fn from(msg: String) -> Self {
96 EvalError::EvalParseError(msg)
97 }
98}
99
100impl From<&str> for EvalError {
101 fn from(msg: &str) -> Self {
102 EvalError::EvalParseError(msg.to_string())
103 }
104}
105
106impl From<ParseError> for EvalError {
107 fn from(msg: ParseError) -> Self {
108 EvalError::EvalParseError(msg.to_string())
109 }
110}
111
112
113pub fn evaluate(input: &str, map: &HashMap<String, RuntimeValue>) -> Result<bool, EvalError> {
135 let evaluator = Evaluator::new(input, map)?;
136 evaluator.eval_boolean(&evaluator.ast)
137
138}
139
140struct Evaluator<'a> {
146 input: String,
147 ast: BooleanExpr,
148 value_map: &'a HashMap<String, RuntimeValue>,
149}
150
151impl<'a> Evaluator<'a> {
152 fn new(input: &str, value_map: &'a HashMap<String, RuntimeValue>) -> Result<Self, EvalError> {
154 let ast = parse(input)?;
155 Ok(Evaluator {
156 input: input.to_string(),
157 ast,
158 value_map,
159 })
160 }
161
162 fn eval_boolean(&self, expr: &BooleanExpr) -> Result<bool, EvalError> {
168 match expr {
169 BooleanExpr::Literal(b) => Ok(*b),
170
171 BooleanExpr::Variable(name) => {
172 match self.value_map.get(name) {
173 Some(RuntimeValue::Boolean(b)) => Ok(*b),
174 Some(other) => Err(EvalError::TypeError {
175 operation: "boolean variable".to_string(),
176 expected: "boolean".to_string(),
177 actual: Self::runtime_type_name(other),
178 context: format!("variable '{}'", name),
179 }),
180 None => Err(EvalError::UnboundVariable {
181 name: name.clone(),
182 }),
183 }
184 }
185
186 BooleanExpr::And(left, right) => {
187 let l = self.eval_boolean(left)?;
188 if !l {
190 return Ok(false);
191 }
192 self.eval_boolean(right)
193 }
194
195 BooleanExpr::Or(left, right) => {
196 let l = self.eval_boolean(left)?;
197 if l {
199 return Ok(true);
200 }
201 self.eval_boolean(right)
202 }
203
204 BooleanExpr::Not(expr) => {
205 Ok(!self.eval_boolean(expr)?)
206 }
207
208 BooleanExpr::Relational(rel) => {
209 self.eval_relational(rel)
210 }
211 }
212 }
213
214 fn eval_relational(&self, expr: &RelationalExpr) -> Result<bool, EvalError> {
220 match expr {
221 RelationalExpr::Equality { left, op, right } => {
222 self.eval_equality(left, right, *op)
223 }
224
225 RelationalExpr::Comparison { left, op, right } => {
226 self.eval_comparison(left, right, *op)
227 }
228
229 RelationalExpr::Like { expr, pattern, escape, negated } => {
230 self.eval_like(expr, pattern, escape.as_ref(), *negated)
231 }
232
233 RelationalExpr::Between { expr, lower, upper, negated } => {
234 self.eval_between(expr, lower, upper, *negated)
235 }
236
237 RelationalExpr::In { expr, values, negated } => {
238 self.eval_in(expr, values, *negated)
239 }
240
241 RelationalExpr::IsNull { expr, negated } => {
242 self.eval_is_null(expr, *negated)
243 }
244 }
245 }
246
247 fn eval_equality(&self, left: &ValueExpr, right: &ValueExpr, op: EqualityOp)
249 -> Result<bool, EvalError>
250 {
251 let l_val = self.eval_value(left)?;
252 let r_val = self.eval_value(right)?;
253
254 if l_val.is_null() || r_val.is_null() {
256 return Err(EvalError::NullInOperation {
257 operation: format!("{:?}", op),
258 context: "cannot compare NULL values (use IS NULL instead)".to_string(),
259 });
260 }
261
262 let equal = match (&l_val, &r_val) {
263 (SubValue::Integer(a), SubValue::Integer(b)) => a == b,
265 (SubValue::Float(a), SubValue::Float(b)) => a == b,
266 (SubValue::Integer(a), SubValue::Float(b)) => (*a as f64) == *b,
267 (SubValue::Float(a), SubValue::Integer(b)) => *a == (*b as f64),
268
269 (SubValue::String(a), SubValue::String(b)) => a == b,
271
272 (SubValue::Boolean(a), SubValue::Boolean(b)) => a == b,
274
275 _ => return Err(EvalError::TypeError {
277 operation: format!("{:?}", op),
278 expected: "matching types".to_string(),
279 actual: format!("{} vs {}", l_val.type_name(), r_val.type_name()),
280 context: "equality comparison".to_string(),
281 }),
282 };
283
284 Ok(match op {
285 EqualityOp::Equal => equal,
286 EqualityOp::NotEqual => !equal,
287 })
288 }
289
290 fn eval_comparison(&self, left: &ValueExpr, right: &ValueExpr, op: ComparisonOp)
292 -> Result<bool, EvalError>
293 {
294 let l_val = self.eval_value(left)?;
295 let r_val = self.eval_value(right)?;
296
297 if l_val.is_null() || r_val.is_null() {
299 return Err(EvalError::NullInOperation {
300 operation: format!("{:?}", op),
301 context: "cannot compare NULL values".to_string(),
302 });
303 }
304
305 match (&l_val, &r_val) {
306 (SubValue::Integer(a), SubValue::Integer(b)) => {
308 Ok(Self::apply_comparison_op(*a, *b, op))
309 }
310 (SubValue::Float(a), SubValue::Float(b)) => {
311 Ok(Self::apply_comparison_op(*a, *b, op))
312 }
313 (SubValue::Integer(a), SubValue::Float(b)) => {
314 Ok(Self::apply_comparison_op(*a as f64, *b, op))
315 }
316 (SubValue::Float(a), SubValue::Integer(b)) => {
317 Ok(Self::apply_comparison_op(*a, *b as f64, op))
318 }
319
320 (SubValue::String(a), SubValue::String(b)) => {
322 Ok(Self::apply_comparison_op(a, b, op))
323 }
324
325 (SubValue::Boolean(_), _) | (_, SubValue::Boolean(_)) => {
327 Err(EvalError::TypeError {
328 operation: format!("{:?}", op),
329 expected: "numeric or string".to_string(),
330 actual: "boolean".to_string(),
331 context: "comparison operand".to_string(),
332 })
333 }
334
335 _ => Err(EvalError::TypeError {
337 operation: format!("{:?}", op),
338 expected: "matching types".to_string(),
339 actual: format!("{} vs {}", l_val.type_name(), r_val.type_name()),
340 context: "comparison".to_string(),
341 }),
342 }
343 }
344
345 fn apply_comparison_op<T: PartialOrd>(a: T, b: T, op: ComparisonOp) -> bool {
346 match op {
347 ComparisonOp::GreaterThan => a > b,
348 ComparisonOp::GreaterOrEqual => a >= b,
349 ComparisonOp::LessThan => a < b,
350 ComparisonOp::LessOrEqual => a <= b,
351 }
352 }
353
354 fn eval_like(&self, expr: &ValueExpr, pattern: &str, escape: Option<&String>, negated: bool)
356 -> Result<bool, EvalError>
357 {
358 let val = self.eval_value(expr)?;
359
360 let string_val = match val {
361 SubValue::String(s) => s,
362 SubValue::Null => {
363 return Err(EvalError::NullInOperation {
364 operation: "LIKE".to_string(),
365 context: "cannot apply LIKE to NULL".to_string(),
366 });
367 }
368 _ => {
369 return Err(EvalError::TypeError {
370 operation: "LIKE".to_string(),
371 expected: "string".to_string(),
372 actual: val.type_name(),
373 context: "left operand".to_string(),
374 });
375 }
376 };
377
378 let matches = Self::match_pattern(&string_val, pattern, escape)?;
379 Ok(if negated { !matches } else { matches })
380 }
381
382 fn match_pattern(s: &str, pattern: &str, escape: Option<&String>) -> Result<bool, EvalError> {
384 let escape_char = escape.and_then(|e| e.chars().next());
385
386 let mut regex_pattern = String::from("^");
388 let mut chars = pattern.chars().peekable();
389
390 while let Some(ch) = chars.next() {
391 if Some(ch) == escape_char {
392 if let Some(next) = chars.next() {
394 regex_pattern.push_str(®ex::escape(&next.to_string()));
395 }
396 } else if ch == '%' {
397 regex_pattern.push_str(".*");
398 } else if ch == '_' {
399 regex_pattern.push('.');
400 } else {
401 regex_pattern.push_str(®ex::escape(&ch.to_string()));
402 }
403 }
404 regex_pattern.push('$');
405
406 let re = regex::Regex::new(®ex_pattern)
407 .map_err(|e| EvalError::InvalidLiteral {
408 literal: pattern.to_string(),
409 literal_type: "LIKE pattern".to_string(),
410 error: format!("{}", e),
411 })?;
412
413 Ok(re.is_match(s))
414 }
415
416 fn eval_between(&self, expr: &ValueExpr, lower: &ValueExpr, upper: &ValueExpr, negated: bool)
418 -> Result<bool, EvalError>
419 {
420 let val = self.eval_value(expr)?;
421 let low = self.eval_value(lower)?;
422 let high = self.eval_value(upper)?;
423
424 if val.is_null() || low.is_null() || high.is_null() {
426 return Err(EvalError::NullInOperation {
427 operation: "BETWEEN".to_string(),
428 context: "cannot use NULL in BETWEEN".to_string(),
429 });
430 }
431
432 let in_range = match (&val, &low, &high) {
434 (SubValue::Integer(v), SubValue::Integer(l), SubValue::Integer(h)) => {
435 v >= l && v <= h
436 }
437 (SubValue::Float(v), SubValue::Float(l), SubValue::Float(h)) => {
438 v >= l && v <= h
439 }
440 (SubValue::String(v), SubValue::String(l), SubValue::String(h)) => {
441 v >= l && v <= h
442 }
443 _ => {
445 let v_num = Self::to_numeric(&val)?;
447 let l_num = Self::to_numeric(&low)?;
448 let h_num = Self::to_numeric(&high)?;
449 v_num >= l_num && v_num <= h_num
450 }
451 };
452
453 Ok(if negated { !in_range } else { in_range })
454 }
455
456 fn eval_in(&self, expr: &ValueExpr, values: &[ValueLiteral], negated: bool)
458 -> Result<bool, EvalError>
459 {
460 let val = self.eval_value(expr)?;
461
462 if val.is_null() {
463 return Err(EvalError::NullInOperation {
464 operation: "IN".to_string(),
465 context: "cannot use NULL in IN".to_string(),
466 });
467 }
468
469 if !values.is_empty() {
472 let first_list_val = SubValue::from_literal(&values[0]);
473 let is_compatible = Self::are_types_compatible_for_in(&val, &first_list_val);
474
475 if !is_compatible {
477 return Err(EvalError::TypeError {
478 operation: "IN".to_string(),
479 expected: first_list_val.type_name(),
480 actual: val.type_name(),
481 context: "left operand type doesn't match list element types".to_string(),
482 });
483 }
484
485 }
487
488 let mut found = false;
489 for lit_val in values {
490 let list_val = SubValue::from_literal(lit_val);
491
492 let matches = match (&val, &list_val) {
494 (SubValue::Integer(a), SubValue::Integer(b)) => a == b,
495 (SubValue::Float(a), SubValue::Float(b)) => a == b,
496 (SubValue::Integer(a), SubValue::Float(b)) => (*a as f64) == *b,
497 (SubValue::Float(a), SubValue::Integer(b)) => *a == (*b as f64),
498 (SubValue::String(a), SubValue::String(b)) => a == b,
499 (SubValue::Boolean(a), SubValue::Boolean(b)) => a == b,
500 (SubValue::Null, SubValue::Null) => true,
501 _ => false, };
503
504 if matches {
505 found = true;
506 break;
507 }
508 }
509
510 Ok(if negated { !found } else { found })
511 }
512
513 fn eval_is_null(&self, expr: &ValueExpr, negated: bool) -> Result<bool, EvalError> {
515 let val = self.eval_value(expr)?;
516 let is_null = val.is_null();
517 Ok(if negated { !is_null } else { is_null })
518 }
519
520 fn eval_value(&self, expr: &ValueExpr) -> Result<SubValue, EvalError> {
526 match expr {
527 ValueExpr::Literal(lit) => Ok(SubValue::from_literal(lit)),
528
529 ValueExpr::Variable(name) => {
530 match self.value_map.get(name) {
531 Some(rv) => Ok(SubValue::from_runtime(rv)),
532 None => Err(EvalError::UnboundVariable {
533 name: name.clone(),
534 }),
535 }
536 }
537
538 ValueExpr::Add(l, r) => self.eval_arithmetic_add(l, r),
539 ValueExpr::Subtract(l, r) => self.eval_arithmetic_subtract(l, r),
540 ValueExpr::Multiply(l, r) => self.eval_arithmetic_multiply(l, r),
541 ValueExpr::Divide(l, r) => self.eval_arithmetic_divide(l, r),
542 ValueExpr::Modulo(l, r) => self.eval_arithmetic_modulo(l, r),
543
544 ValueExpr::UnaryPlus(e) => {
545 let val = self.eval_value(e)?;
546 match val {
547 SubValue::Integer(i) => Ok(SubValue::Integer(i)),
548 SubValue::Float(f) => Ok(SubValue::Float(f)),
549 SubValue::Null => Err(EvalError::NullInOperation {
550 operation: "unary plus".to_string(),
551 context: "cannot apply unary plus to NULL".to_string(),
552 }),
553 _ => Err(EvalError::TypeError {
554 operation: "unary plus".to_string(),
555 expected: "numeric".to_string(),
556 actual: val.type_name(),
557 context: "operand".to_string(),
558 }),
559 }
560 }
561
562 ValueExpr::UnaryMinus(e) => {
563 let val = self.eval_value(e)?;
564 match val {
565 SubValue::Integer(i) => Ok(SubValue::Integer(-i)),
566 SubValue::Float(f) => Ok(SubValue::Float(-f)),
567 SubValue::Null => Err(EvalError::NullInOperation {
568 operation: "unary minus".to_string(),
569 context: "cannot apply unary minus to NULL".to_string(),
570 }),
571 _ => Err(EvalError::TypeError {
572 operation: "unary minus".to_string(),
573 expected: "numeric".to_string(),
574 actual: val.type_name(),
575 context: "operand".to_string(),
576 }),
577 }
578 }
579 }
580 }
581
582 fn eval_arithmetic_add(&self, l: &ValueExpr, r: &ValueExpr) -> Result<SubValue, EvalError> {
584 let left = self.eval_value(l)?;
585 let right = self.eval_value(r)?;
586
587 if left.is_null() || right.is_null() {
589 return Err(EvalError::NullInOperation {
590 operation: "addition".to_string(),
591 context: "cannot add NULL values".to_string(),
592 });
593 }
594
595 match (&left, &right) {
596 (SubValue::Integer(a), SubValue::Integer(b)) => {
597 Ok(SubValue::Integer(a + b))
598 }
599 (SubValue::Float(a), SubValue::Float(b)) => {
600 Ok(SubValue::Float(a + b))
601 }
602 (SubValue::Integer(a), SubValue::Float(b)) => {
604 Ok(SubValue::Float(*a as f64 + b))
605 }
606 (SubValue::Float(a), SubValue::Integer(b)) => {
607 Ok(SubValue::Float(a + *b as f64))
608 }
609 _ => Err(EvalError::TypeError {
610 operation: "addition".to_string(),
611 expected: "numeric types".to_string(),
612 actual: format!("{} and {}", left.type_name(), right.type_name()),
613 context: "arithmetic operation".to_string(),
614 }),
615 }
616 }
617
618 fn eval_arithmetic_subtract(&self, l: &ValueExpr, r: &ValueExpr) -> Result<SubValue, EvalError> {
620 let left = self.eval_value(l)?;
621 let right = self.eval_value(r)?;
622
623 if left.is_null() || right.is_null() {
624 return Err(EvalError::NullInOperation {
625 operation: "subtraction".to_string(),
626 context: "cannot subtract NULL values".to_string(),
627 });
628 }
629
630 match (&left, &right) {
631 (SubValue::Integer(a), SubValue::Integer(b)) => {
632 Ok(SubValue::Integer(a - b))
633 }
634 (SubValue::Float(a), SubValue::Float(b)) => {
635 Ok(SubValue::Float(a - b))
636 }
637 (SubValue::Integer(a), SubValue::Float(b)) => {
638 Ok(SubValue::Float(*a as f64 - b))
639 }
640 (SubValue::Float(a), SubValue::Integer(b)) => {
641 Ok(SubValue::Float(a - *b as f64))
642 }
643 _ => Err(EvalError::TypeError {
644 operation: "subtraction".to_string(),
645 expected: "numeric types".to_string(),
646 actual: format!("{} and {}", left.type_name(), right.type_name()),
647 context: "arithmetic operation".to_string(),
648 }),
649 }
650 }
651
652 fn eval_arithmetic_multiply(&self, l: &ValueExpr, r: &ValueExpr) -> Result<SubValue, EvalError> {
654 let left = self.eval_value(l)?;
655 let right = self.eval_value(r)?;
656
657 if left.is_null() || right.is_null() {
658 return Err(EvalError::NullInOperation {
659 operation: "multiplication".to_string(),
660 context: "cannot multiply NULL values".to_string(),
661 });
662 }
663
664 match (&left, &right) {
665 (SubValue::Integer(a), SubValue::Integer(b)) => {
666 Ok(SubValue::Integer(a * b))
667 }
668 (SubValue::Float(a), SubValue::Float(b)) => {
669 Ok(SubValue::Float(a * b))
670 }
671 (SubValue::Integer(a), SubValue::Float(b)) => {
672 Ok(SubValue::Float(*a as f64 * b))
673 }
674 (SubValue::Float(a), SubValue::Integer(b)) => {
675 Ok(SubValue::Float(a * *b as f64))
676 }
677 _ => Err(EvalError::TypeError {
678 operation: "multiplication".to_string(),
679 expected: "numeric types".to_string(),
680 actual: format!("{} and {}", left.type_name(), right.type_name()),
681 context: "arithmetic operation".to_string(),
682 }),
683 }
684 }
685
686 fn eval_arithmetic_divide(&self, l: &ValueExpr, r: &ValueExpr) -> Result<SubValue, EvalError> {
688 let left = self.eval_value(l)?;
689 let right = self.eval_value(r)?;
690
691 if left.is_null() || right.is_null() {
692 return Err(EvalError::NullInOperation {
693 operation: "division".to_string(),
694 context: "cannot divide NULL values".to_string(),
695 });
696 }
697
698 let left_float = match left {
700 SubValue::Integer(i) => i as f64,
701 SubValue::Float(f) => f,
702 _ => return Err(EvalError::TypeError {
703 operation: "division".to_string(),
704 expected: "numeric".to_string(),
705 actual: left.type_name(),
706 context: "left operand".to_string(),
707 }),
708 };
709
710 let right_float = match right {
711 SubValue::Integer(i) => i as f64,
712 SubValue::Float(f) => f,
713 _ => return Err(EvalError::TypeError {
714 operation: "division".to_string(),
715 expected: "numeric".to_string(),
716 actual: right.type_name(),
717 context: "right operand".to_string(),
718 }),
719 };
720
721 if right_float == 0.0 {
722 return Err(EvalError::DivisionByZero {
723 expression: self.input.clone(),
724 });
725 }
726
727 Ok(SubValue::Float(left_float / right_float))
728 }
729
730 fn eval_arithmetic_modulo(&self, l: &ValueExpr, r: &ValueExpr) -> Result<SubValue, EvalError> {
732 let left = self.eval_value(l)?;
733 let right = self.eval_value(r)?;
734
735 if left.is_null() || right.is_null() {
736 return Err(EvalError::NullInOperation {
737 operation: "modulo".to_string(),
738 context: "cannot modulo NULL values".to_string(),
739 });
740 }
741
742 match (&left, &right) {
743 (SubValue::Integer(a), SubValue::Integer(b)) => {
744 if *b == 0 {
745 return Err(EvalError::DivisionByZero {
746 expression: self.input.clone(),
747 });
748 }
749 Ok(SubValue::Integer(a % b))
750 }
751 (SubValue::Float(a), SubValue::Float(b)) => {
752 if *b == 0.0 {
753 return Err(EvalError::DivisionByZero {
754 expression: self.input.clone(),
755 });
756 }
757 Ok(SubValue::Float(a % b))
758 }
759 (SubValue::Integer(a), SubValue::Float(b)) => {
760 if *b == 0.0 {
761 return Err(EvalError::DivisionByZero {
762 expression: self.input.clone(),
763 });
764 }
765 Ok(SubValue::Float((*a as f64) % b))
766 }
767 (SubValue::Float(a), SubValue::Integer(b)) => {
768 if *b == 0 {
769 return Err(EvalError::DivisionByZero {
770 expression: self.input.clone(),
771 });
772 }
773 Ok(SubValue::Float(a % (*b as f64)))
774 }
775 _ => Err(EvalError::TypeError {
776 operation: "modulo".to_string(),
777 expected: "numeric types".to_string(),
778 actual: format!("{} and {}", left.type_name(), right.type_name()),
779 context: "arithmetic operation".to_string(),
780 }),
781 }
782 }
783
784 fn to_numeric(val: &SubValue) -> Result<f64, EvalError> {
789 match val {
790 SubValue::Integer(i) => Ok(*i as f64),
791 SubValue::Float(f) => Ok(*f),
792 _ => Err(EvalError::TypeError {
793 operation: "numeric comparison".to_string(),
794 expected: "numeric".to_string(),
795 actual: val.type_name(),
796 context: "operand".to_string(),
797 }),
798 }
799 }
800
801 fn are_types_compatible_for_in(left: &SubValue, right: &SubValue) -> bool {
804 match (left, right) {
805 (SubValue::Integer(_), SubValue::Integer(_)) => true,
807 (SubValue::Float(_), SubValue::Float(_)) => true,
808 (SubValue::String(_), SubValue::String(_)) => true,
809 (SubValue::Boolean(_), SubValue::Boolean(_)) => true,
810 (SubValue::Null, SubValue::Null) => true,
811 (SubValue::Integer(_), SubValue::Float(_)) => true,
813 (SubValue::Float(_), SubValue::Integer(_)) => true,
814 _ => false,
816 }
817 }
818
819 fn runtime_type_name(rv: &RuntimeValue) -> String {
820 match rv {
821 RuntimeValue::Integer(_) => "integer".to_string(),
822 RuntimeValue::Float(_) => "float".to_string(),
823 RuntimeValue::String(_) => "string".to_string(),
824 RuntimeValue::Boolean(_) => "boolean".to_string(),
825 RuntimeValue::Null => "NULL".to_string(),
826 }
827 }
828}
829
830#[derive(Debug, Clone, PartialEq)]
836enum SubValue {
837 Integer(i64),
838 Float(f64),
839 String(String),
840 Boolean(bool),
841 Null,
842}
843
844impl SubValue {
845 fn from_runtime(rv: &RuntimeValue) -> Self {
847 match rv {
848 RuntimeValue::Integer(i) => SubValue::Integer(*i),
849 RuntimeValue::Float(f) => SubValue::Float(*f),
850 RuntimeValue::String(s) => SubValue::String(s.clone()),
851 RuntimeValue::Boolean(b) => SubValue::Boolean(*b),
852 RuntimeValue::Null => SubValue::Null,
853 }
854 }
855
856 fn from_literal(lit: &ValueLiteral) -> Self {
858 match lit {
859 ValueLiteral::Integer(i) => SubValue::Integer(*i),
860 ValueLiteral::Float(f) => SubValue::Float(*f),
861 ValueLiteral::String(s) => SubValue::String(s.clone()),
862 ValueLiteral::Boolean(b) => SubValue::Boolean(*b),
863 ValueLiteral::Null => SubValue::Null,
864 }
865 }
866
867 fn type_name(&self) -> String {
868 match self {
869 SubValue::Integer(_) => "integer".to_string(),
870 SubValue::Float(_) => "float".to_string(),
871 SubValue::String(_) => "string".to_string(),
872 SubValue::Boolean(_) => "boolean".to_string(),
873 SubValue::Null => "NULL".to_string(),
874 }
875 }
876
877 fn is_null(&self) -> bool {
878 matches!(self, SubValue::Null)
879 }
880}
881
882