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