boa/syntax/ast/node/break_node/
mod.rs1use super::Node;
2use crate::{
3 exec::Executable,
4 exec::InterpreterState,
5 gc::{Finalize, Trace},
6 Context, JsResult, JsValue,
7};
8use std::fmt;
9
10#[cfg(feature = "deser")]
11use serde::{Deserialize, Serialize};
12
13#[cfg(test)]
14mod tests;
15
16#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
31#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
32pub struct Break {
33 label: Option<Box<str>>,
34}
35
36impl Break {
37 pub fn new<OL, L>(label: OL) -> Self
39 where
40 L: Into<Box<str>>,
41 OL: Into<Option<L>>,
42 {
43 Self {
44 label: label.into().map(L::into),
45 }
46 }
47
48 pub fn label(&self) -> Option<&str> {
50 self.label.as_ref().map(Box::as_ref)
51 }
52}
53
54impl Executable for Break {
55 fn run(&self, context: &mut Context) -> JsResult<JsValue> {
56 context
57 .executor()
58 .set_current_state(InterpreterState::Break(self.label().map(Box::from)));
59
60 Ok(JsValue::undefined())
61 }
62}
63
64impl fmt::Display for Break {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 write!(
67 f,
68 "break{}",
69 if self.label().is_some() {
70 format!(" {}", self.label().as_ref().unwrap())
71 } else {
72 String::new()
73 }
74 )
75 }
76}
77
78impl From<Break> for Node {
79 fn from(break_smt: Break) -> Node {
80 Self::Break(break_smt)
81 }
82}