1use crate::{Block, Expr, ParameterList, Returns, SolIdent, Spanned, kw};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5 Result, Token, parenthesized,
6 parse::{Parse, ParseStream},
7 token::Paren,
8};
9
10#[derive(Clone)]
15pub struct StmtTry {
16 pub try_token: Token![try],
17 pub expr: Box<Expr>,
18 pub returns: Option<Returns>,
19 pub block: Block,
21 pub catch: Vec<CatchClause>,
23}
24
25impl fmt::Debug for StmtTry {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 f.debug_struct("StmtTry")
28 .field("expr", &self.expr)
29 .field("returns", &self.returns)
30 .field("block", &self.block)
31 .field("catch", &self.catch)
32 .finish()
33 }
34}
35
36impl Parse for StmtTry {
37 fn parse(input: ParseStream<'_>) -> Result<Self> {
38 Ok(Self {
39 try_token: input.parse()?,
40 expr: input.parse()?,
41 returns: input.call(Returns::parse_opt)?,
42 block: input.parse()?,
43 catch: {
44 let mut catch = Vec::new();
45 let mut first = true;
46 while first || input.peek(kw::catch) {
47 first = false;
48 catch.push(input.parse()?);
49 }
50 catch
51 },
52 })
53 }
54}
55
56impl Spanned for StmtTry {
57 fn span(&self) -> Span {
58 let span = self.try_token.span;
59 span.join(self.block.span()).unwrap_or(span)
60 }
61
62 fn set_span(&mut self, span: Span) {
63 self.try_token.span = span;
64 self.block.set_span(span);
65 }
66}
67
68#[derive(Clone)]
73pub struct CatchClause {
74 pub catch_token: kw::catch,
75 pub name: Option<SolIdent>,
76 pub paren_token: Option<Paren>,
77 pub list: ParameterList,
78 pub block: Block,
79}
80
81impl fmt::Debug for CatchClause {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 f.debug_struct("CatchClause")
84 .field("name", &self.name)
85 .field("list", &self.list)
86 .field("block", &self.block)
87 .finish()
88 }
89}
90
91impl Parse for CatchClause {
92 fn parse(input: ParseStream<'_>) -> Result<Self> {
93 let catch_token = input.parse()?;
94 let name = input.call(SolIdent::parse_opt)?;
95 let (paren_token, list) = if input.peek(Paren) {
96 let content;
97 (Some(parenthesized!(content in input)), content.parse()?)
98 } else {
99 (None, ParameterList::new())
100 };
101 let block = input.parse()?;
102 Ok(Self { catch_token, name, paren_token, list, block })
103 }
104}
105
106impl Spanned for CatchClause {
107 fn span(&self) -> Span {
108 let span = self.catch_token.span;
109 span.join(self.block.span()).unwrap_or(span)
110 }
111
112 fn set_span(&mut self, span: Span) {
113 self.catch_token.span = span;
114 self.block.set_span(span);
115 }
116}