use crate::{
ShallowClone,
core::{Index, Insert, Remove, Seal, Update},
};
#[doc(hidden)]
pub struct GenericPremap<In, InnerIn, F, Inner> {
f: F,
inner: Inner,
_phantom: core::marker::PhantomData<(In, InnerIn)>,
}
impl<In, InnerIn, F, Inner> Clone for GenericPremap<In, InnerIn, F, Inner>
where
F: Copy,
Inner: Clone,
{
fn clone(&self) -> Self {
GenericPremap {
f: self.f,
inner: self.inner.clone(),
_phantom: core::marker::PhantomData,
}
}
}
impl<In, InnerIn, F, Inner> ShallowClone for GenericPremap<In, InnerIn, F, Inner>
where
Inner: ShallowClone,
F: Copy,
{
}
pub type Premap<In, InnerIn, Inner> = GenericPremap<In, InnerIn, fn(&In) -> &InnerIn, Inner>;
pub type PremapOwned<In, InnerIn, Inner> = GenericPremap<In, InnerIn, fn(&In) -> InnerIn, Inner>;
impl<In, InnerIn, Inner> Premap<In, InnerIn, Inner> {
pub fn new(f: fn(&In) -> &InnerIn, inner: Inner) -> Self {
Premap {
f,
inner,
_phantom: core::marker::PhantomData,
}
}
}
impl<In, InnerIn, Inner> PremapOwned<In, InnerIn, Inner> {
pub fn new(f: fn(&In) -> InnerIn, inner: Inner) -> Self {
PremapOwned {
f,
inner,
_phantom: core::marker::PhantomData,
}
}
}
impl<In, InnerIn, Inner> Index<In> for Premap<In, InnerIn, Inner>
where
Inner: Index<InnerIn>,
{
#[inline]
fn insert(&mut self, seal: Seal, op: &Insert<In>) {
self.inner.insert(
seal,
&Insert {
key: op.key,
new: (self.f)(op.new),
},
);
}
#[inline]
fn update(&mut self, seal: Seal, op: &Update<In>) {
self.inner.update(
seal,
&Update {
key: op.key,
new: (self.f)(op.new),
existing: (self.f)(op.existing),
},
);
}
#[inline]
fn remove(&mut self, seal: Seal, op: &Remove<In>) {
self.inner.remove(
seal,
&Remove {
key: op.key,
existing: (self.f)(op.existing),
},
);
}
}
impl<In, InnerIn, Inner> Index<In> for PremapOwned<In, InnerIn, Inner>
where
Inner: Index<InnerIn>,
{
#[inline]
fn insert(&mut self, seal: Seal, op: &Insert<In>) {
self.inner.insert(
seal,
&Insert {
key: op.key,
new: &(self.f)(op.new),
},
);
}
#[inline]
fn update(&mut self, seal: Seal, op: &Update<In>) {
self.inner.update(
seal,
&Update {
key: op.key,
new: &(self.f)(op.new),
existing: &(self.f)(op.existing),
},
);
}
#[inline]
fn remove(&mut self, seal: Seal, op: &Remove<In>) {
self.inner.remove(
seal,
&Remove {
key: op.key,
existing: &(self.f)(op.existing),
},
);
}
}
impl<In, InnerIn, F, Inner> GenericPremap<In, InnerIn, F, Inner> {
#[inline]
pub fn inner(&self) -> &Inner {
&self.inner
}
}
impl<In, InnerIn, F, Inner> core::ops::Deref for GenericPremap<In, InnerIn, F, Inner> {
type Target = Inner;
fn deref(&self) -> &Self::Target {
&self.inner
}
}