use std::fmt::Display;
use ltk_hash::{BinHash, HashValue};
use crate::span::Span;
use crate::Spanned;
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "span_print", derive(crate::span::DebugSpans))]
pub struct HashedLiteral<H> {
pub value: H,
pub originally: Spanned<Originally>,
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Originally {
#[default]
HexLit,
String,
Name,
Null,
}
impl<H> HashedLiteral<H> {
#[inline(always)]
#[must_use]
pub fn new(span: Span, originally: Originally, value: H) -> Self {
Self {
value,
originally: Spanned::new(span, originally),
}
}
#[inline(always)]
#[must_use]
pub fn with_span(mut self, span: Span) -> Self {
self.originally.span = span;
self
}
#[inline(always)]
#[must_use]
pub fn with_value<NewHash>(self, value: NewHash) -> HashedLiteral<NewHash> {
HashedLiteral {
value,
originally: self.originally,
}
}
#[inline(always)]
#[must_use]
pub fn span(&self) -> Span {
self.originally.span
}
#[inline(always)]
#[must_use]
pub fn original_kind(&self) -> Originally {
self.originally.value
}
#[inline(always)]
#[must_use]
pub fn was_hash(&self) -> bool {
matches!(self.original_kind(), Originally::HexLit)
}
#[inline(always)]
#[must_use]
pub fn was_str(&self) -> bool {
matches!(self.original_kind(), Originally::String)
}
#[inline(always)]
#[must_use]
pub fn was_name(&self) -> bool {
matches!(self.original_kind(), Originally::Name)
}
}
impl HashedLiteral<HashValue> {
#[inline(always)]
#[must_use]
pub fn try_as_bin_hash(self) -> Option<HashedLiteral<BinHash>> {
let value = self.value.try_as_bin_hash()?;
Some(self.with_value(value))
}
}
impl<H: Display> Display for HashedLiteral<H> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "0x{}", self.value)
}
}