galvan_ast/item/
literal.rs

1use derive_more::From;
2use typeunion::type_union;
3
4use galvan_ast_macro::AstNode;
5
6use crate::{AstNode, Expression, Span};
7
8#[type_union]
9#[derive(Clone, Debug, PartialEq, Eq, AstNode)]
10pub type Literal = StringLiteral + NumberLiteral + BooleanLiteral + NoneLiteral + CharLiteral;
11
12#[derive(Clone, Debug, PartialEq, Eq, From)]
13pub struct StringLiteral {
14    pub value: String,
15    pub interpolations: Vec<Expression>, // Expressions found in {expr} within the string
16    pub span: Span,
17}
18
19impl AstNode for StringLiteral {
20    fn span(&self) -> Span {
21        self.span
22    }
23
24    fn print(&self, indent: usize) -> String {
25        if self.interpolations.is_empty() {
26            format!("{}\"{}\"", " ".repeat(indent), self.value)
27        } else {
28            format!("{}\"{}\" (with {} interpolations)", " ".repeat(indent), self.value, self.interpolations.len())
29        }
30    }
31}
32
33impl StringLiteral {
34    pub fn as_str(&self) -> &str {
35        &self.value
36    }
37}
38
39impl From<StringLiteral> for String {
40    fn from(string: StringLiteral) -> Self {
41        string.value
42    }
43}
44
45impl AsRef<str> for StringLiteral {
46    fn as_ref(&self) -> &str {
47        self.as_str()
48    }
49}
50
51#[derive(Clone, Debug, PartialEq, Eq)]
52// TODO: Parse number literal and validate type
53pub struct NumberLiteral {
54    pub value: String,
55    pub span: Span,
56}
57
58impl AstNode for NumberLiteral {
59    fn span(&self) -> Span {
60        self.span
61    }
62
63    fn print(&self, indent: usize) -> String {
64        format!("{}{}", " ".repeat(indent), self.value)
65    }
66}
67
68impl NumberLiteral {
69    pub fn as_str(&self) -> &str {
70        &self.value
71    }
72}
73
74#[derive(Clone, Copy, Debug, PartialEq, Eq, From)]
75pub struct BooleanLiteral {
76    pub value: bool,
77    pub span: Span,
78}
79
80impl AstNode for BooleanLiteral {
81    fn span(&self) -> Span {
82        self.span
83    }
84
85    fn print(&self, indent: usize) -> String {
86        format!("{}{}", " ".repeat(indent), self.value)
87    }
88}
89
90#[derive(Clone, Copy, Debug, PartialEq, Eq)]
91pub struct NoneLiteral(pub Span);
92
93impl AstNode for NoneLiteral {
94    fn span(&self) -> Span {
95        self.0
96    }
97
98    fn print(&self, indent: usize) -> String {
99        format!("{}None", " ".repeat(indent))
100    }
101}
102
103#[derive(Clone, Debug, PartialEq, Eq)]
104pub struct CharLiteral {
105    pub value: char,
106    pub span: Span,
107}
108
109impl AstNode for CharLiteral {
110    fn span(&self) -> Span {
111        self.span
112    }
113
114    fn print(&self, indent: usize) -> String {
115        format!("{}'{}'", " ".repeat(indent), self.value)
116    }
117}
118
119impl CharLiteral {
120    pub fn as_char(&self) -> char {
121        self.value
122    }
123}