use crate::ast::{EntityUID, Integer, StaticallyTyped, Type};
use crate::parser;
use smol_str::SmolStr;
use std::sync::Arc;
#[derive(Hash, Debug, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub enum Literal {
Bool(bool),
Long(Integer),
String(SmolStr),
EntityUID(Arc<EntityUID>),
}
impl StaticallyTyped for Literal {
fn type_of(&self) -> Type {
match self {
Self::Bool(_) => Type::Bool,
Self::Long(_) => Type::Long,
Self::String(_) => Type::String,
Self::EntityUID(uid) => uid.type_of(),
}
}
}
impl std::fmt::Display for Literal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Bool(b) => write!(f, "{b}"),
Self::Long(i) => write!(f, "{i}"),
Self::String(s) => write!(f, "\"{}\"", s.escape_debug()),
Self::EntityUID(uid) => write!(f, "{uid}"),
}
}
}
impl std::str::FromStr for Literal {
type Err = parser::err::LiteralParseError;
fn from_str(s: &str) -> Result<Literal, Self::Err> {
parser::parse_literal(s)
}
}
impl From<bool> for Literal {
fn from(b: bool) -> Self {
Self::Bool(b)
}
}
impl From<Integer> for Literal {
fn from(i: Integer) -> Self {
Self::Long(i)
}
}
impl From<String> for Literal {
fn from(s: String) -> Self {
Self::String(SmolStr::new(s))
}
}
impl From<&str> for Literal {
fn from(s: &str) -> Self {
Self::String(SmolStr::new(s))
}
}
impl From<SmolStr> for Literal {
fn from(s: SmolStr) -> Self {
Self::String(s)
}
}
impl From<EntityUID> for Literal {
fn from(e: EntityUID) -> Self {
Self::EntityUID(Arc::new(e))
}
}
impl From<Arc<EntityUID>> for Literal {
fn from(ptr: Arc<EntityUID>) -> Self {
Self::EntityUID(ptr)
}
}
impl Literal {
pub fn is_ref(&self) -> bool {
matches!(self, Self::EntityUID(..))
}
}