1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use crate::comment::Comment;
use crate::expr::{Function, Signature};
use crate::ident::Ident;
use crate::node::Spanned;
use crate::operator::{InfixDirection, Precedence};
use crate::pattern::Pattern;
use crate::type_annotation::TypeAnnotation;
/// A top-level declaration in an Elm module.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Declaration {
/// A function or value definition.
///
/// ```elm
/// add : Int -> Int -> Int
/// add x y = x + y
/// ```
FunctionDeclaration(Box<Function>),
/// A type alias declaration.
///
/// ```elm
/// type alias Model =
/// { count : Int
/// , name : String
/// }
/// ```
AliasDeclaration(TypeAlias),
/// A custom type (ADT / tagged union) declaration.
///
/// ```elm
/// type Msg
/// = Increment
/// | Decrement
/// | SetName String
/// ```
CustomTypeDeclaration(CustomType),
/// A port declaration.
///
/// ```elm
/// port sendMessage : String -> Cmd msg
/// ```
PortDeclaration(Signature),
/// An infix operator declaration (only in core packages).
///
/// ```elm
/// infix left 6 (+) = add
/// ```
InfixDeclaration(InfixDef),
/// A top-level destructuring (rare, but valid).
///
/// ```elm
/// { name, age } = person
/// ```
Destructuring {
pattern: Spanned<Pattern>,
body: Spanned<crate::expr::Expr>,
},
}
/// A type alias definition.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TypeAlias {
/// Optional documentation comment.
pub documentation: Option<Spanned<String>>,
/// The alias name: `Model`
pub name: Spanned<Ident>,
/// Type parameters: `a`, `b` in `type alias Result a b = ...`
pub generics: Vec<Spanned<Ident>>,
/// The type being aliased.
pub type_annotation: Spanned<TypeAnnotation>,
}
/// A custom type (ADT / tagged union) definition.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CustomType {
/// Optional documentation comment.
pub documentation: Option<Spanned<String>>,
/// The type name: `Msg`
pub name: Spanned<Ident>,
/// Type parameters: `a` in `type Maybe a = ...`
pub generics: Vec<Spanned<Ident>>,
/// Comments that appear between the type name/generics and the `=`.
/// elm-format preserves these by wrapping the `type` header over two
/// lines:
/// type
/// Sequence value
/// -- repeat, delay, duration
/// = Sequence ...
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
pub pre_equals_comments: Vec<Spanned<Comment>>,
/// The constructors: `Just a | Nothing`
pub constructors: Vec<Spanned<ValueConstructor>>,
}
/// A value constructor in a custom type definition.
///
/// `Just a` → `ValueConstructor { name: "Just", args: [a] }`
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ValueConstructor {
pub name: Spanned<Ident>,
pub args: Vec<Spanned<TypeAnnotation>>,
/// Comments that appeared BEFORE the preceding `|` separator (or for the
/// first constructor, before `=`). elm-format preserves these as
/// "trailing on previous constructor" style: they appear on their own
/// line(s) at the constructor-name column, with the `|` for THIS
/// constructor coming afterward on a new line. Leave empty for the
/// first constructor.
#[cfg_attr(feature = "serde", serde(default))]
pub pre_pipe_comments: Vec<Spanned<Comment>>,
/// Optional trailing inline comment on the same source line as the
/// constructor: `| Ctor args -- comment`. elm-format keeps the comment
/// on the same line after the last arg.
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub trailing_comment: Option<Spanned<Comment>>,
}
/// An infix operator definition.
///
/// `infix left 6 (+) = add`
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct InfixDef {
pub direction: Spanned<InfixDirection>,
pub precedence: Spanned<Precedence>,
pub operator: Spanned<Ident>,
pub function: Spanned<Ident>,
}