1use crate::{Expr, Spanned, Stmt};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5 parse::{Parse, ParseStream},
6 token::Paren,
7 Result, Token,
8};
9
10#[derive(Clone)]
13pub struct StmtIf {
14 pub if_token: Token![if],
15 pub paren_token: Paren,
16 pub cond: Expr,
17 pub then_branch: Box<Stmt>,
18 pub else_branch: Option<(Token![else], Box<Stmt>)>,
19}
20
21impl fmt::Debug for StmtIf {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 f.debug_struct("StmtIf")
24 .field("cond", &self.cond)
25 .field("then_branch", &self.then_branch)
26 .field("else_branch", &self.else_branch)
27 .finish()
28 }
29}
30
31impl Parse for StmtIf {
32 fn parse(input: ParseStream<'_>) -> Result<Self> {
33 let content;
34 Ok(Self {
35 if_token: input.parse()?,
36 paren_token: syn::parenthesized!(content in input),
37 cond: content.parse()?,
38 then_branch: input.parse()?,
39 else_branch: if input.peek(Token![else]) {
40 Some((input.parse()?, input.parse()?))
41 } else {
42 None
43 },
44 })
45 }
46}
47
48impl Spanned for StmtIf {
49 fn span(&self) -> Span {
50 let span = self.if_token.span;
51 self.else_branch
52 .as_ref()
53 .and_then(|(_, stmt)| stmt.span().join(span))
54 .or_else(|| span.join(self.then_branch.span()))
55 .unwrap_or(span)
56 }
57
58 fn set_span(&mut self, span: Span) {
59 self.if_token.span = span;
60 self.then_branch.set_span(span);
61 if let Some((_, stmt)) = &mut self.else_branch {
62 stmt.set_span(span);
63 }
64 }
65}