use core::ops::AddAssign;
use crate::utils::{Lexeme, human_display::DisplayHuman};
use super::{PositionedChar, SimpleSpan};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SingleCharEscape<Char = char, O = usize> {
character: PositionedChar<Char, O>,
span: SimpleSpan<O>,
}
impl<Char, O> core::fmt::Display for SingleCharEscape<Char, O>
where
Char: DisplayHuman,
O: core::fmt::Display,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "\\{} at {}", self.char_ref().display(), self.span)
}
}
impl<Char, O> SingleCharEscape<Char, O> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn from_char(span: SimpleSpan<O>, pos: O, ch: Char) -> Self {
Self::from_positioned_char(span, PositionedChar::with_position(ch, pos))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_positioned_char(
span: SimpleSpan<O>,
character: PositionedChar<Char, O>,
) -> Self {
Self { character, span }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn char(&self) -> Char
where
Char: Copy,
{
self.character.char()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn char_ref(&self) -> &Char {
self.character.char_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn char_mut(&mut self) -> &mut Char {
self.character.char_mut()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn position(&self) -> O
where
O: Copy,
{
self.character.position()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn position_ref(&self) -> &O {
self.character.position_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span(&self) -> SimpleSpan<O>
where
O: Copy,
{
self.span
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span_ref(&self) -> SimpleSpan<&O> {
self.span.as_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span_mut(&mut self) -> SimpleSpan<&mut O> {
self.span.as_mut()
}
#[inline]
pub fn bump(&mut self, offset: &O) -> &mut Self
where
O: for<'a> AddAssign<&'a O> + Clone,
{
self.span.bump(offset);
self.character.bump_position(offset);
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MultiCharEscape<S = SimpleSpan> {
content: S,
span: S,
}
impl<S> core::fmt::Display for MultiCharEscape<S>
where
S: core::fmt::Display,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "escape sequence at {}", self.span)
}
}
impl<S> MultiCharEscape<S> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(content: S, span: S) -> Self {
Self { content, span }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn content(&self) -> S
where
S: Copy,
{
self.content
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn content_ref(&self) -> &S {
&self.content
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn content_mut(&mut self) -> &mut S {
&mut self.content
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span(&self) -> S
where
S: Copy,
{
self.span
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span_ref(&self) -> &S {
&self.span
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span_mut(&mut self) -> &mut S {
&mut self.span
}
#[inline]
pub fn bump(&mut self, offset: &S::Offset) -> &mut Self
where
S: crate::lexer::Span,
{
self.span.bump(offset);
self.content.bump(offset);
self
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct EscapedLexeme<Char = char, O = usize> {
span: SimpleSpan<O>,
lexeme: Lexeme<Char, O>,
}
impl<Char, O> core::fmt::Display for EscapedLexeme<Char, O>
where
Char: DisplayHuman,
O: core::fmt::Display,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.lexeme {
Lexeme::Char(ref ch) => write!(f, "\\{} at {}", ch.char_ref().display(), ch.position_ref()),
Lexeme::Range(ref range) => write!(f, "escape sequence at {}", range),
}
}
}
impl<Char, O> EscapedLexeme<Char, O> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(span: SimpleSpan<O>, lexeme: Lexeme<Char, O>) -> Self {
Self { span, lexeme }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_positioned_char(span: SimpleSpan<O>, ch: PositionedChar<Char, O>) -> Self {
Self::new(span, Lexeme::Char(ch))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_char(span: SimpleSpan<O>, pos: O, ch: Char) -> Self {
Self::from_positioned_char(span, PositionedChar::with_position(ch, pos))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_sequence(span: SimpleSpan<O>, content: SimpleSpan<O>) -> Self {
Self::new(span, Lexeme::Range(content))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span(&self) -> SimpleSpan<O>
where
O: Copy,
{
self.span
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span_ref(&self) -> SimpleSpan<&O> {
self.span.as_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn span_mut(&mut self) -> SimpleSpan<&mut O> {
self.span.as_mut()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn lexeme(&self) -> Lexeme<Char, O>
where
Char: Copy,
O: Copy,
{
self.lexeme
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn lexeme_ref(&self) -> &Lexeme<Char, O> {
&self.lexeme
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn lexeme_mut(&mut self) -> &mut Lexeme<Char, O> {
&mut self.lexeme
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn bump(&mut self, offset: &O) -> &mut Self
where
O: for<'a> AddAssign<&'a O> + Clone,
{
self.span.bump(offset);
self.lexeme.bump(offset);
self
}
}