Skip to main content

mago_type_syntax/ast/
object.rs

1use serde::Serialize;
2
3use mago_span::HasSpan;
4use mago_span::Span;
5use mago_syntax_core::ast::Sequence;
6
7use crate::ast::Keyword;
8use crate::ast::ShapeField;
9
10#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
11pub struct ObjectType<'arena> {
12    pub keyword: Keyword<'arena>,
13    pub properties: Option<ObjectProperties<'arena>>,
14}
15
16#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
17pub struct ObjectProperties<'arena> {
18    pub left_brace: Span,
19    pub fields: Sequence<'arena, ShapeField<'arena>>,
20    pub ellipsis: Option<Span>,
21    pub right_brace: Span,
22}
23
24impl HasSpan for ObjectType<'_> {
25    fn span(&self) -> Span {
26        match &self.properties {
27            Some(parameters) => self.keyword.span.join(parameters.span()),
28            None => self.keyword.span,
29        }
30    }
31}
32
33impl std::fmt::Display for ObjectType<'_> {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        if let Some(parameters) = &self.properties {
36            write!(f, "{}{}", self.keyword, parameters)
37        } else {
38            write!(f, "{}", self.keyword)
39        }
40    }
41}
42
43impl HasSpan for ObjectProperties<'_> {
44    fn span(&self) -> Span {
45        self.left_brace.join(self.right_brace)
46    }
47}
48
49impl std::fmt::Display for ObjectProperties<'_> {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        write!(f, "{{")?;
52        for (i, field) in self.fields.iter().enumerate() {
53            if i > 0 {
54                write!(f, ", {field}")?;
55            } else {
56                write!(f, "{field}")?;
57            }
58        }
59
60        if self.ellipsis.is_some() {
61            if !self.fields.is_empty() {
62                write!(f, ", ")?;
63            }
64
65            write!(f, "...")?;
66        }
67
68        write!(f, "}}")
69    }
70}