Evaluate an expression with an optional context. The context must implement the provided trait `[Context]`, that can get an `[crate::graph::element::Element]` using a given key. # Examples ``` # use dyn_type::Object; # use ir_common::NameOrId; # use graph_proxy::utils::expr::eval::{Context, Evaluator, Evaluate}; # use graph_proxy::apis::{Vertex, DynDetails}; # use ahash::HashMap; # use std::conv
(&self, context: Option<&C>)
| 509 | /// assert!(eval.eval_bool::<_, _>(Some(&ctxt)).unwrap()) |
| 510 | /// ``` |
| 511 | fn eval<E: Element, C: Context<E>>(&self, context: Option<&C>) -> ExprEvalResult<Object> { |
| 512 | let mut stack = self.stack.borrow_mut(); |
| 513 | if self.suffix_tree.len() <= 3 { |
| 514 | return self.eval_without_stack(context); |
| 515 | } |
| 516 | stack.clear(); |
| 517 | for opr in &self.suffix_tree { |
| 518 | if opr.is_operand() { |
| 519 | stack.push(opr.eval(context)); |
| 520 | } else { |
| 521 | if let Some(first) = stack.pop() { |
| 522 | let rst = match opr { |
| 523 | InnerOpr::Logical(logical) => { |
| 524 | if logical == &common_pb::Logical::Not { |
| 525 | apply_logical(logical, first?.as_borrow(), None) |
| 526 | } else if logical == &common_pb::Logical::Isnull { |
| 527 | let first_obj = match first { |
| 528 | Ok(obj) => obj, |
| 529 | Err(err) => match err { |
| 530 | ExprEvalError::GetNoneFromContext => Object::None, |
| 531 | _ => return Err(err), |
| 532 | }, |
| 533 | }; |
| 534 | apply_logical(logical, first_obj.as_borrow(), None) |
| 535 | } else { |
| 536 | if let Some(second) = stack.pop() { |
| 537 | apply_logical(logical, second?.as_borrow(), Some(first?.as_borrow())) |
| 538 | } else { |
| 539 | Err(ExprEvalError::OtherErr("invalid expression".to_string())) |
| 540 | } |
| 541 | } |
| 542 | } |
| 543 | InnerOpr::Function(function) => { |
| 544 | if opr.is_unary() { |
| 545 | apply_function(function, first?.as_borrow(), None) |
| 546 | } else { |
| 547 | if let Some(second) = stack.pop() { |
| 548 | apply_function(function, second?.as_borrow(), Some(first?.as_borrow())) |
| 549 | } else { |
| 550 | Err(ExprEvalError::OtherErr("invalid expression".to_string())) |
| 551 | } |
| 552 | } |
| 553 | } |
| 554 | InnerOpr::Arith(arith) => { |
| 555 | if let Some(second) = stack.pop() { |
| 556 | apply_arith(arith, second?.as_borrow(), first?.as_borrow()) |
| 557 | } else { |
| 558 | Err(ExprEvalError::OtherErr("invalid expression".to_string())) |
| 559 | } |
| 560 | } |
| 561 | _ => unreachable!(), |
| 562 | }; |
| 563 | stack.push(rst); |
| 564 | } |
| 565 | } |
| 566 | } |
| 567 | |
| 568 | if stack.len() == 1 { |
no test coverage detected