use crate::utils::marker::Ignored;
use super::{AsSpan, IntoComponents, IntoSpan, SimpleSpan};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct Spanned<D, S = SimpleSpan> {
pub span: S,
pub data: D,
}
impl<D, S> AsRef<S> for Spanned<D, S> {
#[cfg_attr(not(tarpaulin), inline(always))]
fn as_ref(&self) -> &S {
self.span_ref()
}
}
impl<D, S> AsSpan<S> for Spanned<D, S> {
#[cfg_attr(not(tarpaulin), inline(always))]
fn as_span(&self) -> &S {
AsRef::as_ref(self)
}
}
impl<D, S> IntoSpan<S> for Spanned<D, S> {
#[cfg_attr(not(tarpaulin), inline(always))]
fn into_span(self) -> S {
self.span
}
}
impl<D, S> core::ops::Deref for Spanned<D, S> {
type Target = D;
#[cfg_attr(not(tarpaulin), inline(always))]
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<D, S> core::ops::DerefMut for Spanned<D, S> {
#[cfg_attr(not(tarpaulin), inline(always))]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl<D, S> core::fmt::Display for Spanned<D, S>
where
D: core::fmt::Display,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.data.fmt(f)
}
}
impl<D, S> core::error::Error for Spanned<D, S>
where
D: core::error::Error,
S: core::fmt::Debug,
{
}
impl<D, S> IntoComponents for Spanned<D, S> {
type Components = (S, D);
#[cfg_attr(not(tarpaulin), inline(always))]
fn into_components(self) -> Self::Components {
(self.span, self.data)
}
}
impl<D, S> Spanned<&D, &S> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn copied(&self) -> Spanned<D, S>
where
D: Copy,
S: Copy,
{
Spanned {
span: *self.span,
data: *self.data,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn cloned(&self) -> Spanned<D, S>
where
D: Clone,
S: Clone,
{
self.map(Clone::clone, Clone::clone)
}
}
impl<D, S> Spanned<D, S> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(span: S, data: D) -> Self {
Self { span, data }
}
#[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
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn data(&self) -> &D {
&self.data
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn data_mut(&mut self) -> &mut D {
&mut self.data
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_ref(&self) -> Spanned<&D, &S> {
Spanned {
span: &self.span,
data: &self.data,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_mut(&mut self) -> Spanned<&mut D, &mut S> {
Spanned {
span: &mut self.span,
data: &mut self.data,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn into_span(self) -> S {
self.span
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn into_data(self) -> D {
self.data
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn into_components(self) -> (S, D) {
(self.span, self.data)
}
#[inline]
pub fn map_data<F, U>(self, f: F) -> Spanned<U, S>
where
F: FnOnce(D) -> U,
{
Spanned {
span: self.span,
data: f(self.data),
}
}
#[inline]
pub fn map_span<F, T>(self, f: F) -> Spanned<D, T>
where
F: FnOnce(S) -> T,
{
Spanned {
span: f(self.span),
data: self.data,
}
}
#[inline]
pub fn map<F, G, U, T>(self, f: F, g: G) -> Spanned<U, T>
where
F: FnOnce(S) -> T,
G: FnOnce(D) -> U,
{
Spanned {
span: f(self.span),
data: g(self.data),
}
}
}
impl<D, S> From<Spanned<D, S>> for () {
#[cfg_attr(not(tarpaulin), inline(always))]
fn from(_: Spanned<D, S>) -> Self {}
}
impl<D, S> From<Spanned<D, S>> for Ignored<()> {
#[cfg_attr(not(tarpaulin), inline(always))]
fn from(_: Spanned<D, S>) -> Self {
Ignored::default()
}
}