use super::{
traits::{Storable, Word},
FixedVec,
};
use dsi_bitstream::prelude::Endianness;
use std::{
fmt,
mem,
ops::{Deref, DerefMut},
};
pub struct MutProxy<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
vec: &'a mut FixedVec<T, W, E, B>,
index: usize,
value: T,
}
impl<T, W, E, B> fmt::Debug for MutProxy<'_, T, W, E, B>
where
T: Storable<W> + fmt::Debug,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MutProxy")
.field("index", &self.index)
.field("value", &self.value)
.finish()
}
}
impl<'a, T, W, E, B> MutProxy<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
pub(super) fn new(vec: &'a mut FixedVec<T, W, E, B>, index: usize) -> Self {
let value = vec
.get(index)
.expect("Index out of bounds in MutProxy creation");
Self { vec, index, value }
}
pub fn into_inner(self) -> T {
let value = self.value;
mem::forget(self);
value
}
}
impl<T, W, E, B> Deref for MutProxy<'_, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<T, W, E, B> DerefMut for MutProxy<'_, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
}
impl<T, W, E, B> Drop for MutProxy<'_, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
fn drop(&mut self) {
self.vec.set(self.index, self.value);
}
}