mago_type_syntax/ast/
callable.rs1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::Type;
8use crate::ast::keyword::Keyword;
9
10#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
11#[serde(tag = "type", content = "value")]
12pub enum CallableTypeKind {
13 Callable,
14 PureCallable,
15 Closure,
16 PureClosure,
17}
18
19#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
20#[repr(C)]
21pub struct CallableType<'input> {
22 pub kind: CallableTypeKind,
23 pub keyword: Keyword<'input>,
24 pub specification: Option<CallableTypeSpecification<'input>>,
25}
26
27#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
28#[repr(C)]
29pub struct CallableTypeSpecification<'input> {
30 pub parameters: CallableTypeParameters<'input>,
31 pub return_type: Option<CallableTypeReturnType<'input>>,
32}
33
34#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
35#[repr(C)]
36pub struct CallableTypeParameters<'input> {
37 pub left_parenthesis: Span,
38 pub entries: Vec<CallableTypeParameter<'input>>,
39 pub right_parenthesis: Span,
40}
41
42#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
43#[repr(C)]
44pub struct CallableTypeParameter<'input> {
45 pub parameter_type: Box<Type<'input>>,
46 pub equals: Option<Span>,
47 pub ellipsis: Option<Span>,
48 pub comma: Option<Span>,
49}
50
51#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
52#[repr(C)]
53pub struct CallableTypeReturnType<'input> {
54 pub colon: Span,
55 pub return_type: Box<Type<'input>>,
56}
57
58impl HasSpan for CallableType<'_> {
59 fn span(&self) -> Span {
60 match &self.specification {
61 Some(specification) => self.keyword.span.join(specification.span()),
62 None => self.keyword.span,
63 }
64 }
65}
66
67impl HasSpan for CallableTypeSpecification<'_> {
68 fn span(&self) -> Span {
69 match &self.return_type {
70 Some(return_type) => self.parameters.span().join(return_type.span()),
71 None => self.parameters.span(),
72 }
73 }
74}
75
76impl HasSpan for CallableTypeParameters<'_> {
77 fn span(&self) -> Span {
78 self.left_parenthesis.join(self.right_parenthesis)
79 }
80}
81
82impl HasSpan for CallableTypeParameter<'_> {
83 fn span(&self) -> Span {
84 match &self.comma {
85 Some(comma) => self.parameter_type.span().join(*comma),
86 None => match &self.ellipsis {
87 Some(ellipsis) => self.parameter_type.span().join(*ellipsis),
88 None => match &self.equals {
89 Some(equals) => self.parameter_type.span().join(*equals),
90 None => self.parameter_type.span(),
91 },
92 },
93 }
94 }
95}
96
97impl HasSpan for CallableTypeReturnType<'_> {
98 fn span(&self) -> Span {
99 self.colon.join(self.return_type.span())
100 }
101}