boa/syntax/ast/node/conditional/if_node/
mod.rs1use crate::{
2 exec::Executable,
3 gc::{Finalize, Trace},
4 syntax::ast::node::Node,
5 Context, JsResult, JsValue,
6};
7use std::fmt;
8
9#[cfg(feature = "deser")]
10use serde::{Deserialize, Serialize};
11
12#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
29#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
30pub struct If {
31 cond: Box<Node>,
32 body: Box<Node>,
33 else_node: Option<Box<Node>>,
34}
35
36impl If {
37 pub fn cond(&self) -> &Node {
38 &self.cond
39 }
40
41 pub fn body(&self) -> &Node {
42 &self.body
43 }
44
45 pub fn else_node(&self) -> Option<&Node> {
46 self.else_node.as_ref().map(Box::as_ref)
47 }
48
49 pub fn new<C, B, E, OE>(condition: C, body: B, else_node: OE) -> Self
51 where
52 C: Into<Node>,
53 B: Into<Node>,
54 E: Into<Node>,
55 OE: Into<Option<E>>,
56 {
57 Self {
58 cond: Box::new(condition.into()),
59 body: Box::new(body.into()),
60 else_node: else_node.into().map(E::into).map(Box::new),
61 }
62 }
63
64 pub(in crate::syntax::ast::node) fn display(
65 &self,
66 f: &mut fmt::Formatter<'_>,
67 indent: usize,
68 ) -> fmt::Result {
69 write!(f, "if ({}) ", self.cond())?;
70 match self.else_node() {
71 Some(else_e) => {
72 self.body().display(f, indent)?;
73 f.write_str(" else ")?;
74 else_e.display(f, indent)
75 }
76 None => self.body().display(f, indent),
77 }
78 }
79}
80
81impl Executable for If {
82 fn run(&self, context: &mut Context) -> JsResult<JsValue> {
83 Ok(if self.cond().run(context)?.to_boolean() {
84 self.body().run(context)?
85 } else if let Some(else_e) = self.else_node() {
86 else_e.run(context)?
87 } else {
88 JsValue::undefined()
89 })
90 }
91}
92
93impl fmt::Display for If {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 self.display(f, 0)
96 }
97}
98
99impl From<If> for Node {
100 fn from(if_stm: If) -> Node {
101 Self::If(if_stm)
102 }
103}