use std::{
fmt::Display,
ops::{Deref, DerefMut},
};
use crate::Span;
#[derive(Debug)]
pub struct Sliced<'source, T> {
pub inner: T,
span: Span,
source: &'source str,
}
impl<'source, T> Sliced<'source, T> {
pub fn new(inner: T, span: Span, source: &'source str) -> Self {
Self {
inner,
span,
source,
}
}
pub fn unwrap(self) -> T {
self.inner
}
pub fn span(&self) -> Span {
self.span.clone()
}
pub fn slice(&self) -> &'source str {
&self.source[self.span.clone()]
}
pub fn source(&self) -> &'source str {
self.source
}
}
impl<'source, T, E> Sliced<'source, Result<T, E>> {
pub fn unzip(self) -> Result<Sliced<'source, T>, Sliced<'source, E>> {
match self.inner {
Ok(t) => Ok(Sliced::new(t, self.span, self.source)),
Err(e) => Err(Sliced::new(e, self.span, self.source)),
}
}
}
impl<'source, T> Sliced<'source, Option<T>> {
pub fn unzip(self) -> Option<Sliced<'source, T>> {
match self.inner {
Some(t) => Some(Sliced::new(t, self.span, self.source)),
None => None,
}
}
}
impl<'source, T> Sliced<'source, &T> {
pub fn copied(self) -> Sliced<'source, T>
where
T: Copy,
{
Sliced {
inner: *self.inner,
span: self.span.clone(),
source: self.source,
}
}
pub fn cloned(self) -> Sliced<'source, T>
where
T: Clone,
{
Sliced {
inner: self.inner.clone(),
span: self.span.clone(),
source: self.source,
}
}
}
impl<'source, T> Sliced<'source, &mut T> {
pub fn copied(self) -> Sliced<'source, T>
where
T: Copy,
{
Sliced {
inner: *self.inner,
span: self.span.clone(),
source: self.source,
}
}
pub fn cloned(self) -> Sliced<'source, T>
where
T: Clone,
{
Sliced {
inner: self.inner.clone(),
span: self.span.clone(),
source: self.source,
}
}
}
impl<T> Clone for Sliced<'_, T>
where
T: Clone,
{
fn clone(&self) -> Self {
Sliced {
inner: self.inner.clone(),
span: self.span.clone(),
source: self.source,
}
}
}
impl<T> Deref for Sliced<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> DerefMut for Sliced<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<'source, T> AsRef<T> for Sliced<'source, T>
where
<Sliced<'source, T> as Deref>::Target: AsRef<T>,
{
fn as_ref(&self) -> &T {
self.deref()
}
}
impl<'source, T> AsMut<T> for Sliced<'source, T>
where
<Sliced<'source, T> as Deref>::Target: AsMut<T>,
{
fn as_mut(&mut self) -> &mut T {
self.deref_mut()
}
}
impl<'a, 'source, T> From<&'a Sliced<'source, T>> for Sliced<'source, &'a T> {
fn from(value: &'a Sliced<'source, T>) -> Self {
Sliced {
inner: &value.inner,
span: value.span.clone(),
source: value.source,
}
}
}
impl<'a, 'source, T> From<&'a mut Sliced<'source, T>> for Sliced<'source, &'a mut T> {
fn from(value: &'a mut Sliced<'source, T>) -> Self {
Sliced {
inner: &mut value.inner,
span: value.span.clone(),
source: value.source,
}
}
}
impl<T: PartialEq> PartialEq for Sliced<'_, T> {
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner && self.span == other.span && self.source == other.source
}
}
impl<T: Display> Display for Sliced<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}(\"{}\")", self.inner, self.slice())
}
}