use core::fmt;
use serde::{Deserialize, Serialize};
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default, Serialize, Deserialize)]
pub struct BytePos(usize);
impl BytePos {
#[inline(always)]
pub fn shift(self, ch: char) -> Self {
BytePos(self.0 + ch.len_utf8())
}
#[inline(always)]
pub fn shift_by(self, n: usize) -> Self {
BytePos(self.0 + n)
}
}
impl fmt::Display for BytePos {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<usize> for BytePos {
fn from(value: usize) -> Self {
BytePos(value)
}
}
impl From<BytePos> for usize {
fn from(value: BytePos) -> Self {
value.0
}
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default, Serialize, Deserialize)]
pub struct Span {
pub start: BytePos,
pub end: BytePos,
}
impl Span {
pub unsafe fn new_unchecked(start: usize, end: usize) -> Self {
Span {
start: BytePos(start),
end: BytePos(end),
}
}
#[inline]
pub const fn empty() -> Self {
Span {
start: BytePos(0),
end: BytePos(0),
}
}
pub fn union_span(self, other: Self) -> Self {
use std::cmp;
Span {
start: cmp::min(self.start, other.start),
end: cmp::max(self.end, other.end),
}
}
}
impl fmt::Display for Span {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}:{}]", self.start, self.end)
}
}
pub trait Spanned {
fn span(&self) -> Span;
fn start(&self) -> usize {
self.span().start.0
}
fn end(&self) -> usize {
self.span().end.0
}
}
impl Spanned for Span {
#[inline(always)]
fn span(&self) -> Span {
*self
}
}