boa_ast/statement/iteration/
break.rs1use boa_interner::{Interner, Sym, ToInternedString};
2use core::ops::ControlFlow;
3
4use crate::Statement;
5use crate::visitor::{VisitWith, Visitor, VisitorMut};
6
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub struct Break {
25 label: Option<Sym>,
26}
27
28impl Break {
29 #[must_use]
31 pub const fn new(label: Option<Sym>) -> Self {
32 Self { label }
33 }
34
35 #[must_use]
37 pub const fn label(&self) -> Option<Sym> {
38 self.label
39 }
40}
41
42impl ToInternedString for Break {
43 fn to_interned_string(&self, interner: &Interner) -> String {
44 self.label.map_or_else(
45 || "break".to_owned(),
46 |label| format!("break {}", interner.resolve_expect(label)),
47 )
48 }
49}
50
51impl From<Break> for Statement {
52 fn from(break_smt: Break) -> Self {
53 Self::Break(break_smt)
54 }
55}
56
57impl VisitWith for Break {
58 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
59 where
60 V: Visitor<'a>,
61 {
62 if let Some(sym) = &self.label {
63 visitor.visit_sym(sym)
64 } else {
65 ControlFlow::Continue(())
66 }
67 }
68
69 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
70 where
71 V: VisitorMut<'a>,
72 {
73 if let Some(sym) = &mut self.label {
74 visitor.visit_sym_mut(sym)
75 } else {
76 ControlFlow::Continue(())
77 }
78 }
79}