use core::marker::PhantomData;
use crate::{
Field,
lenses::LensesMut,
type_lists::{
Concat,
ConsSet,
GetPtr,
SculptPtr,
TupleSet,
},
};
#[derive(Debug)]
pub struct LensMut<'a, T>
where
T: TupleSet,
{
storage: T::ConsPtr,
_phantom: PhantomData<&'a mut ()>,
}
impl<'a, T> LensesMut<'a, T> for LensMut<'a, T>
where
T: TupleSet,
{
#[inline]
fn lens_mut(self) -> Self {
self
}
}
impl<'a, T> LensMut<'a, T>
where
T: TupleSet,
{
#[inline]
#[must_use]
pub(crate) const fn new(storage: T::ConsPtr) -> Self {
Self {
storage,
_phantom: PhantomData,
}
}
#[expect(clippy::type_complexity, reason = "necessary type inference")]
#[inline]
#[must_use]
pub fn split<Lhs, Indices>(
self,
) -> (
LensMut<'a, Lhs>,
LensMut<
'a,
<<T::ConsPtr as SculptPtr<Lhs::ConsPtr, Indices>>::Remainder as ConsSet>::Tuple,
>,
)
where
Lhs: TupleSet,
T::ConsPtr: SculptPtr<Lhs::ConsPtr, Indices>,
<T::ConsPtr as SculptPtr<Lhs::ConsPtr, Indices>>::Remainder: ConsSet<
Tuple: TupleSet<ConsPtr = <T::ConsPtr as SculptPtr<Lhs::ConsPtr, Indices>>::Remainder>,
>,
{
let (lhs_storage, rem_storage) = self.storage.sculpt_ptr();
(
LensMut {
storage: lhs_storage,
_phantom: PhantomData,
},
LensMut {
storage: rem_storage,
_phantom: PhantomData,
},
)
}
#[expect(clippy::type_complexity, reason = "necessary type inference")]
#[inline]
#[must_use]
pub fn join<Rhs>(
self,
other: LensMut<'a, Rhs>,
) -> LensMut<'a, <<T::ConsPtr as Concat<T::ConsPtr, Rhs::ConsPtr>>::Result as ConsSet>::Tuple>
where
Rhs: TupleSet,
T::ConsPtr: Concat<T::ConsPtr, Rhs::ConsPtr>,
<T::ConsPtr as Concat<T::ConsPtr, Rhs::ConsPtr>>::Result: ConsSet<
Tuple: TupleSet<ConsPtr = <T::ConsPtr as Concat<T::ConsPtr, Rhs::ConsPtr>>::Result>,
>,
{
LensMut {
storage: self.storage.concat(other.storage),
_phantom: PhantomData,
}
}
#[inline]
#[must_use]
pub fn as_ptr<Elt, Index>(&self) -> *const Elt::Type
where
Elt: Field,
T::ConsPtr: GetPtr<Elt, Index>,
{
self.storage.get_ptr().as_ptr()
}
#[inline]
#[must_use]
pub fn as_mut_ptr<Elt, Index>(&mut self) -> *mut Elt::Type
where
Elt: Field,
T::ConsPtr: GetPtr<Elt, Index>,
{
self.storage.get_ptr().as_ptr()
}
#[expect(
clippy::should_implement_trait,
reason = "signature is generic over the field type, not interchangeable with `AsRef`"
)]
#[inline]
#[must_use]
pub fn as_ref<Elt, Index>(&self) -> &Elt::Type
where
Elt: Field,
T::ConsPtr: GetPtr<Elt, Index>,
{
unsafe { &*self.storage.get_ptr().as_ptr() }
}
#[expect(
clippy::should_implement_trait,
reason = "signature is generic over the field type, not interchangeable with `AsMut`"
)]
#[inline]
#[must_use]
pub fn as_mut<Elt, Index>(&mut self) -> &mut Elt::Type
where
Elt: Field,
T::ConsPtr: GetPtr<Elt, Index>,
{
unsafe { &mut *self.storage.get_ptr().as_ptr() }
}
}