syn_solidity/yul/stmt/
switch.rs1use crate::{Lit, Spanned, YulBlock, YulExpr, kw};
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 = { if input.peek(kw::default) { Some(input.parse()?) } else { None } };
40
41 if branches.is_empty() && default_case.is_none() {
42 return Err(input.error("Must have at least one case or a default case."));
43 }
44
45 Ok(Self { switch_token, selector, branches, default_case })
46 }
47}
48
49impl Spanned for YulSwitch {
50 fn span(&self) -> Span {
51 let span = self.switch_token.span();
52 if let Some(default_case) = &self.default_case {
53 return span.join(default_case.span()).unwrap_or(span);
54 }
55 span.join(self.branches.span()).unwrap_or(span)
56 }
57
58 fn set_span(&mut self, span: Span) {
59 self.switch_token.set_span(span);
60 self.selector.set_span(span);
61 self.branches.set_span(span);
62 self.default_case.set_span(span);
63 }
64}
65
66impl fmt::Debug for YulSwitch {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 f.debug_struct("YulSwitch")
69 .field("selector", &self.selector)
70 .field("branches", &self.branches)
71 .field("default_case", &self.default_case)
72 .finish()
73 }
74}
75
76#[derive(Clone)]
78pub struct YulCaseBranch {
79 pub case_token: kw::case,
80 pub constant: Lit,
81 pub body: YulBlock,
82}
83
84impl Parse for YulCaseBranch {
85 fn parse(input: ParseStream<'_>) -> Result<Self> {
86 Ok(Self { case_token: input.parse()?, constant: input.parse()?, body: input.parse()? })
87 }
88}
89
90impl Spanned for YulCaseBranch {
91 fn span(&self) -> Span {
92 let span = self.case_token.span();
93 span.join(self.body.span()).unwrap_or(span)
94 }
95
96 fn set_span(&mut self, span: Span) {
97 self.case_token.set_span(span);
98 self.constant.set_span(span);
99 self.body.set_span(span);
100 }
101}
102
103impl fmt::Debug for YulCaseBranch {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 f.debug_struct("YulCaseBranch")
106 .field("constant", &self.constant)
107 .field("body", &self.body)
108 .finish()
109 }
110}
111
112#[derive(Clone)]
114pub struct YulSwitchDefault {
115 pub default_token: kw::default,
116 pub body: YulBlock,
117}
118
119impl Parse for YulSwitchDefault {
120 fn parse(input: ParseStream<'_>) -> Result<Self> {
121 Ok(Self { default_token: input.parse()?, body: input.parse()? })
122 }
123}
124
125impl Spanned for YulSwitchDefault {
126 fn span(&self) -> Span {
127 let span = self.default_token.span();
128 span.join(self.body.span()).unwrap_or(span)
129 }
130
131 fn set_span(&mut self, span: Span) {
132 self.default_token.set_span(span);
133 self.body.set_span(span);
134 }
135}
136
137impl fmt::Debug for YulSwitchDefault {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 f.debug_struct("SwitchDefault").field("body", &self.body).finish()
140 }
141}