use core::ops::Add;
use super::CharLen;
use crate::utils::SimpleSpan;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PositionedChar<Char, Offset = usize> {
char: Char,
pub(crate) position: Offset,
}
impl<Char, Offset> PositionedChar<Char, Offset> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_position(char: Char, position: Offset) -> Self {
Self { char, position }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn char(&self) -> Char
where
Char: Copy,
{
self.char
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn char_ref(&self) -> &Char {
&self.char
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn char_mut(&mut self) -> &mut Char {
&mut self.char
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn position_ref(&self) -> &Offset {
&self.position
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn position(&self) -> Offset
where
Offset: Copy,
{
self.position
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn span(&self) -> SimpleSpan<Offset>
where
Char: CharLen,
Offset: Clone + Ord,
for<'a> &'a Offset: Add<usize, Output = Offset>,
{
let start = self.position_ref();
let end = start + self.char_ref().char_len();
SimpleSpan::new(start.clone(), end)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn set_position(&mut self, position: Offset) -> &mut Self {
self.position = position;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn bump_position<'a>(&'a mut self, n: &'a Offset) -> &'a mut Self
where
Offset: core::ops::AddAssign<&'a Offset>,
{
self.position += n;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_ref(&self) -> PositionedChar<&Char, &Offset> {
PositionedChar {
char: &self.char,
position: &self.position,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_mut(&mut self) -> PositionedChar<&mut Char, &mut Offset> {
PositionedChar {
char: &mut self.char,
position: &mut self.position,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn map<NewChar, F>(self, f: F) -> PositionedChar<NewChar, Offset>
where
F: FnOnce(Char) -> NewChar,
{
PositionedChar {
char: f(self.char),
position: self.position,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn into_components(self) -> (Char, Offset) {
(self.char, self.position)
}
}
impl<Char: core::fmt::Display, Offset> core::fmt::Display for PositionedChar<Char, Offset> {
#[cfg_attr(not(tarpaulin), inline(always))]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.char)
}
}