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