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
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>>,
/// 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>>,
}
/// 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>,
}