syn_solidity/yul/stmt/
switch.rs1use crate::{kw, Lit, Spanned, YulBlock, YulExpr};
2use proc_macro2::Span;
3use std::fmt;
4use syn::parse::{Parse, ParseStream, Result};
5
6#[derive(Clone)]
21pub struct YulSwitch {
22 pub switch_token: kw::switch,
23 pub selector: YulExpr,
24 pub branches: Vec<YulCaseBranch>,
25 pub default_case: Option<YulSwitchDefault>,
26}
27
28impl Parse for YulSwitch {
29 fn parse(input: ParseStream<'_>) -> Result<Self> {
30 let switch_token = input.parse()?;
31 let selector = input.parse()?;
32 let branches = {
33 let mut branches = vec![];
34 while input.peek(kw::case) {
35 branches.push(input.parse()?);
36 }
37 branches
38 };
39 let default_case = {
40 if input.peek(kw::default) {
41 Some(input.parse()?)
42 } else {
43 None
44 }
45 };
46
47 if branches.is_empty() && default_case.is_none() {
48 return Err(input.error("Must have at least one case or a default case."));
49 }
50
51 Ok(Self { switch_token, selector, branches, default_case })
52 }
53}
54
55impl Spanned for YulSwitch {
56 fn span(&self) -> Span {
57 let span = self.switch_token.span();
58 if let Some(default_case) = &self.default_case {
59 return span.join(default_case.span()).unwrap_or(span);
60 }
61 span.join(self.branches.span()).unwrap_or(span)
62 }
63
64 fn set_span(&mut self, span: Span) {
65 self.switch_token.set_span(span);
66 self.selector.set_span(span);
67 self.branches.set_span(span);
68 self.default_case.set_span(span);
69 }
70}
71
72impl fmt::Debug for YulSwitch {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 f.debug_struct("YulSwitch")
75 .field("selector", &self.selector)
76 .field("branches", &self.branches)
77 .field("default_case", &self.default_case)
78 .finish()
79 }
80}
81
82#[derive(Clone)]
84pub struct YulCaseBranch {
85 pub case_token: kw::case,
86 pub constant: Lit,
87 pub body: YulBlock,
88}
89
90impl Parse for YulCaseBranch {
91 fn parse(input: ParseStream<'_>) -> Result<Self> {
92 Ok(Self { case_token: input.parse()?, constant: input.parse()?, body: input.parse()? })
93 }
94}
95
96impl Spanned for YulCaseBranch {
97 fn span(&self) -> Span {
98 let span = self.case_token.span();
99 span.join(self.body.span()).unwrap_or(span)
100 }
101
102 fn set_span(&mut self, span: Span) {
103 self.case_token.set_span(span);
104 self.constant.set_span(span);
105 self.body.set_span(span);
106 }
107}
108
109impl fmt::Debug for YulCaseBranch {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 f.debug_struct("YulCaseBranch")
112 .field("constant", &self.constant)
113 .field("body", &self.body)
114 .finish()
115 }
116}
117
118#[derive(Clone)]
120pub struct YulSwitchDefault {
121 pub default_token: kw::default,
122 pub body: YulBlock,
123}
124
125impl Parse for YulSwitchDefault {
126 fn parse(input: ParseStream<'_>) -> Result<Self> {
127 Ok(Self { default_token: input.parse()?, body: input.parse()? })
128 }
129}
130
131impl Spanned for YulSwitchDefault {
132 fn span(&self) -> Span {
133 let span = self.default_token.span();
134 span.join(self.body.span()).unwrap_or(span)
135 }
136
137 fn set_span(&mut self, span: Span) {
138 self.default_token.set_span(span);
139 self.body.set_span(span);
140 }
141}
142
143impl fmt::Debug for YulSwitchDefault {
144 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145 f.debug_struct("SwitchDefault").field("body", &self.body).finish()
146 }
147}