1use sway_error::handler::ErrorEmitted;
2
3use crate::priv_prelude::*;
4
5#[derive(Clone, Debug, Serialize)]
6pub enum Pattern {
7 Or {
8 lhs: Box<Pattern>,
9 pipe_token: PipeToken,
10 rhs: Box<Pattern>,
11 },
12 Wildcard {
13 underscore_token: UnderscoreToken,
14 },
15 AmbiguousSingleIdent(Ident),
17 Var {
18 reference: Option<RefToken>, mutable: Option<MutToken>,
20 name: Ident,
21 },
22 Literal(Literal),
23 Constant(PathExpr),
24 Constructor {
25 path: PathExpr,
26 args: Parens<Punctuated<Pattern, CommaToken>>,
27 },
28 Struct {
29 path: PathExpr,
30 fields: Braces<Punctuated<PatternStructField, CommaToken>>,
31 },
32 Tuple(Parens<Punctuated<Pattern, CommaToken>>),
33 Error(Box<[Span]>, #[serde(skip_serializing)] ErrorEmitted),
35}
36
37impl Spanned for Pattern {
38 fn span(&self) -> Span {
39 match self {
40 Pattern::Or {
41 lhs,
42 pipe_token,
43 rhs,
44 } => Span::join(Span::join(lhs.span(), &pipe_token.span()), &rhs.span()),
45 Pattern::Wildcard { underscore_token } => underscore_token.span(),
46 Pattern::Var {
47 reference,
48 mutable,
49 name,
50 } => match (reference, mutable) {
51 (Some(ref_token), Some(mut_token)) => Span::join(
52 Span::join(ref_token.span(), &mut_token.span()),
53 &name.span(),
54 ),
55 (Some(ref_token), None) => Span::join(ref_token.span(), &name.span()),
56 (None, Some(mut_token)) => Span::join(mut_token.span(), &name.span()),
57 (None, None) => name.span(),
58 },
59 Pattern::AmbiguousSingleIdent(ident) => ident.span(),
60 Pattern::Literal(literal) => literal.span(),
61 Pattern::Constant(path_expr) => path_expr.span(),
62 Pattern::Constructor { path, args } => Span::join(path.span(), &args.span()),
63 Pattern::Struct { path, fields } => Span::join(path.span(), &fields.span()),
64 Pattern::Tuple(pat_tuple) => pat_tuple.span(),
65 Pattern::Error(spans, _) => spans
66 .iter()
67 .cloned()
68 .reduce(|s1: Span, s2: Span| Span::join(s1, &s2))
69 .unwrap(),
70 }
71 }
72}
73
74#[derive(Clone, Debug, Serialize)]
75pub enum PatternStructField {
76 Rest {
77 token: DoubleDotToken,
78 },
79 Field {
80 field_name: Ident,
81 pattern_opt: Option<(ColonToken, Box<Pattern>)>,
82 },
83}
84
85impl Spanned for PatternStructField {
86 fn span(&self) -> Span {
87 use PatternStructField::*;
88 match &self {
89 Rest { token } => token.span(),
90 Field {
91 field_name,
92 pattern_opt,
93 } => match pattern_opt {
94 Some((_colon_token, pattern)) => Span::join(field_name.span(), &pattern.span()),
95 None => field_name.span(),
96 },
97 }
98 }
99}