mago_type_syntax/ast/
callable.rs

1use 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}