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 {
24 let mut lhs = lhs.into();
25 let rhs = rhs.into();
26
27 match (&mut lhs, rhs) {
28 (expr, rhs) if expr.is_true() => rhs,
29 (_, expr) if expr.is_true() => lhs,
30 (Self::And(lhs_and), Self::And(rhs_and)) => {
31 lhs_and.operands.extend(rhs_and.operands);
32 lhs
33 }
34 (Self::And(lhs_and), rhs) => {
35 lhs_and.operands.push(rhs);
36 lhs
37 }
38 (_, Self::And(mut rhs_and)) => {
39 rhs_and.operands.push(lhs);
40 rhs_and.into()
41 }
42 (_, rhs) => ExprAnd {
43 operands: vec![lhs, rhs],
44 }
45 .into(),
46 }
47 }
48
49 pub fn and_from_vec(operands: Vec<Self>) -> Self {
50 if operands.is_empty() {
51 return true.into();
52 }
53
54 if operands.len() == 1 {
55 return operands.into_iter().next().unwrap();
56 }
57
58 ExprAnd { operands }.into()
59 }
60}
61
62impl ops::Deref for ExprAnd {
63 type Target = [Expr];
64
65 fn deref(&self) -> &Self::Target {
66 self.operands.deref()
67 }
68}
69
70impl<'a> IntoIterator for &'a ExprAnd {
71 type IntoIter = std::slice::Iter<'a, Expr>;
72 type Item = &'a Expr;
73
74 fn into_iter(self) -> Self::IntoIter {
75 self.operands.iter()
76 }
77}
78
79impl<'a> IntoIterator for &'a mut ExprAnd {
80 type IntoIter = std::slice::IterMut<'a, Expr>;
81 type Item = &'a mut Expr;
82
83 fn into_iter(self) -> Self::IntoIter {
84 self.operands.iter_mut()
85 }
86}
87
88impl From<ExprAnd> for Expr {
89 fn from(value: ExprAnd) -> Self {
90 Self::And(value)
91 }
92}