use crate::*;
#[derive(
Debug,
ToOutput,
InlineOutput,
Tagged,
ListHashes,
Topological,
Clone,
Copy,
Size,
MaybeHasNiche,
PartialEq,
Eq,
)]
pub struct MappedExtra<T, M = ()>(pub M, pub T);
impl<T, M> Deref for MappedExtra<T, M> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.1
}
}
impl<T, M> DerefMut for MappedExtra<T, M> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.1
}
}
#[derive_for_wrapped]
pub trait MapExtra<Extra: 'static + Clone = ()> {
type Mapped: 'static + Clone;
fn map_extra(&self, extra: Extra) -> Self::Mapped;
}
impl<
M: 'static + Send + Sync + Clone + ParseInline<I> + MapExtra<X, Mapped = E>,
E: 'static + Send + Sync + Clone,
X: 'static + Send + Sync + Clone,
T: Parse<J>,
I: PointInput<Extra = X, WithExtra<E> = J>,
J: ParseInput,
> Parse<I> for MappedExtra<T, M>
{
fn parse(mut input: I) -> crate::Result<Self> {
let m = input.parse_inline::<M>()?;
let x = input.extra().clone();
let t = input.parse_extra(m.map_extra(x))?;
Ok(Self(m, t))
}
}
impl<
M: 'static + Send + Sync + Clone + ParseInline<I> + MapExtra<X, Mapped = E>,
E: 'static + Send + Sync + Clone,
X: 'static + Send + Sync + Clone,
T: ParseInline<J>,
I: PointInput<Extra = X, WithExtra<E> = J>,
J: ParseInput,
> ParseInline<I> for MappedExtra<T, M>
{
fn parse_inline(input: &mut I) -> crate::Result<Self> {
let m = input.parse_inline::<M>()?;
let x = input.extra().clone();
let t = input.parse_inline_extra(m.map_extra(x))?;
Ok(Self(m, t))
}
}