toasty_core/stmt/
expr_and.rs1use super::Expr;
2
3use std::ops;
4
5#[derive(Debug, Clone, PartialEq)]
17pub struct ExprAnd {
18 pub operands: Vec<Expr>,
20}
21
22impl Expr {
23 pub fn and(lhs: impl Into<Self>, rhs: impl Into<Self>) -> Self {
28 let mut lhs = lhs.into();
29 let rhs = rhs.into();
30
31 match (&mut lhs, rhs) {
32 (expr, rhs) if expr.is_true() => rhs,
33 (_, expr) if expr.is_true() => lhs,
34 (Self::And(lhs_and), Self::And(rhs_and)) => {
35 lhs_and.operands.extend(rhs_and.operands);
36 lhs
37 }
38 (Self::And(lhs_and), rhs) => {
39 lhs_and.operands.push(rhs);
40 lhs
41 }
42 (_, Self::And(mut rhs_and)) => {
43 rhs_and.operands.push(lhs);
44 rhs_and.into()
45 }
46 (_, rhs) => ExprAnd {
47 operands: vec![lhs, rhs],
48 }
49 .into(),
50 }
51 }
52
53 pub fn and_from_vec(operands: Vec<Self>) -> Self {
58 if operands.is_empty() {
59 return true.into();
60 }
61
62 if operands.len() == 1 {
63 return operands.into_iter().next().unwrap();
64 }
65
66 ExprAnd { operands }.into()
67 }
68}
69
70impl ops::Deref for ExprAnd {
71 type Target = [Expr];
72
73 fn deref(&self) -> &Self::Target {
74 self.operands.deref()
75 }
76}
77
78impl<'a> IntoIterator for &'a ExprAnd {
79 type IntoIter = std::slice::Iter<'a, Expr>;
80 type Item = &'a Expr;
81
82 fn into_iter(self) -> Self::IntoIter {
83 self.operands.iter()
84 }
85}
86
87impl<'a> IntoIterator for &'a mut ExprAnd {
88 type IntoIter = std::slice::IterMut<'a, Expr>;
89 type Item = &'a mut Expr;
90
91 fn into_iter(self) -> Self::IntoIter {
92 self.operands.iter_mut()
93 }
94}
95
96impl From<ExprAnd> for Expr {
97 fn from(value: ExprAnd) -> Self {
98 Self::And(value)
99 }
100}