use derive_more::From;
use typeunion::type_union;
use galvan_ast_macro::AstNode;
use crate::{AstNode, Expression, Span};
#[type_union]
#[derive(Clone, Debug, PartialEq, Eq, AstNode)]
pub type Literal = StringLiteral + NumberLiteral + BooleanLiteral + NoneLiteral + CharLiteral;
#[derive(Clone, Debug, PartialEq, Eq, From)]
pub struct StringLiteral {
pub value: String,
pub interpolations: Vec<Expression>, pub span: Span,
}
impl AstNode for StringLiteral {
fn span(&self) -> Span {
self.span
}
fn print(&self, indent: usize) -> String {
if self.interpolations.is_empty() {
format!("{}\"{}\"", " ".repeat(indent), self.value)
} else {
format!("{}\"{}\" (with {} interpolations)", " ".repeat(indent), self.value, self.interpolations.len())
}
}
}
impl StringLiteral {
pub fn as_str(&self) -> &str {
&self.value
}
}
impl From<StringLiteral> for String {
fn from(string: StringLiteral) -> Self {
string.value
}
}
impl AsRef<str> for StringLiteral {
fn as_ref(&self) -> &str {
self.as_str()
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NumberLiteral {
pub value: String,
pub span: Span,
}
impl AstNode for NumberLiteral {
fn span(&self) -> Span {
self.span
}
fn print(&self, indent: usize) -> String {
format!("{}{}", " ".repeat(indent), self.value)
}
}
impl NumberLiteral {
pub fn as_str(&self) -> &str {
&self.value
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, From)]
pub struct BooleanLiteral {
pub value: bool,
pub span: Span,
}
impl AstNode for BooleanLiteral {
fn span(&self) -> Span {
self.span
}
fn print(&self, indent: usize) -> String {
format!("{}{}", " ".repeat(indent), self.value)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct NoneLiteral(pub Span);
impl AstNode for NoneLiteral {
fn span(&self) -> Span {
self.0
}
fn print(&self, indent: usize) -> String {
format!("{}None", " ".repeat(indent))
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CharLiteral {
pub value: char,
pub span: Span,
}
impl AstNode for CharLiteral {
fn span(&self) -> Span {
self.span
}
fn print(&self, indent: usize) -> String {
format!("{}'{}'", " ".repeat(indent), self.value)
}
}
impl CharLiteral {
pub fn as_char(&self) -> char {
self.value
}
}