syn_solidity/yul/stmt/
switch.rsuse crate::{kw, Lit, Spanned, YulBlock, YulExpr};
use proc_macro2::Span;
use std::fmt;
use syn::parse::{Parse, ParseStream, Result};
#[derive(Clone)]
pub struct YulSwitch {
pub switch_token: kw::switch,
pub selector: YulExpr,
pub branches: Vec<YulCaseBranch>,
pub default_case: Option<YulSwitchDefault>,
}
impl Parse for YulSwitch {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let switch_token = input.parse()?;
let selector = input.parse()?;
let branches = {
let mut branches = vec![];
while input.peek(kw::case) {
branches.push(input.parse()?);
}
branches
};
let default_case = {
if input.peek(kw::default) {
Some(input.parse()?)
} else {
None
}
};
if branches.is_empty() && default_case.is_none() {
return Err(input.error("Must have at least one case or a default case."));
}
Ok(Self { switch_token, selector, branches, default_case })
}
}
impl Spanned for YulSwitch {
fn span(&self) -> Span {
let span = self.switch_token.span();
if let Some(default_case) = &self.default_case {
return span.join(default_case.span()).unwrap_or(span);
}
span.join(self.branches.span()).unwrap_or(span)
}
fn set_span(&mut self, span: Span) {
self.switch_token.set_span(span);
self.selector.set_span(span);
self.branches.set_span(span);
self.default_case.set_span(span);
}
}
impl fmt::Debug for YulSwitch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("YulSwitch")
.field("selector", &self.selector)
.field("branches", &self.branches)
.field("default_case", &self.default_case)
.finish()
}
}
#[derive(Clone)]
pub struct YulCaseBranch {
pub case_token: kw::case,
pub constant: Lit,
pub body: YulBlock,
}
impl Parse for YulCaseBranch {
fn parse(input: ParseStream<'_>) -> Result<Self> {
Ok(Self { case_token: input.parse()?, constant: input.parse()?, body: input.parse()? })
}
}
impl Spanned for YulCaseBranch {
fn span(&self) -> Span {
let span = self.case_token.span();
span.join(self.body.span()).unwrap_or(span)
}
fn set_span(&mut self, span: Span) {
self.case_token.set_span(span);
self.constant.set_span(span);
self.body.set_span(span);
}
}
impl fmt::Debug for YulCaseBranch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("YulCaseBranch")
.field("constant", &self.constant)
.field("body", &self.body)
.finish()
}
}
#[derive(Clone)]
pub struct YulSwitchDefault {
pub default_token: kw::default,
pub body: YulBlock,
}
impl Parse for YulSwitchDefault {
fn parse(input: ParseStream<'_>) -> Result<Self> {
Ok(Self { default_token: input.parse()?, body: input.parse()? })
}
}
impl Spanned for YulSwitchDefault {
fn span(&self) -> Span {
let span = self.default_token.span();
span.join(self.body.span()).unwrap_or(span)
}
fn set_span(&mut self, span: Span) {
self.default_token.set_span(span);
self.body.set_span(span);
}
}
impl fmt::Debug for YulSwitchDefault {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SwitchDefault").field("body", &self.body).finish()
}
}