1use core::borrow::Borrow;
2use core::marker::PhantomData;
3
4use super::traits::{Get, GetMut, Project, ToIndex};
5
6pub struct ViewMut<'a, K: ?Sized + ToIndex, P, S: GetMut<K>>
7where
8 S::Output: Project<P>,
9{
10 data: &'a mut S,
11 _k: PhantomData<K>,
12 _proj: PhantomData<P>,
13}
14
15impl<'a, K: ?Sized + ToIndex, P, S: GetMut<K>> ViewMut<'a, K, P, S>
16where
17 S::Output: Project<P>,
18{
19 pub fn new(data: &'a mut S) -> Self {
20 Self {
21 data,
22 _k: PhantomData,
23 _proj: PhantomData,
24 }
25 }
26
27 pub fn with<F: FnOnce(&mut Self) -> R, R>(data: &'a mut S, f: F) -> R {
28 let mut view = Self::new(data);
29 f(&mut view)
30 }
31}
32
33impl<'a, K: ?Sized + ToIndex, P, S: GetMut<K>> Get<K> for ViewMut<'a, K, P, S>
34where
35 S::Output: Project<P>,
36{
37 type Output = P;
38
39 fn get<Q: Borrow<K>>(&self, idx: Q) -> Option<&P> {
40 self.data.get(idx).and_then(Project::project)
41 }
42}
43
44impl<'a, K: ?Sized + ToIndex, P, S: GetMut<K>> GetMut<K> for ViewMut<'a, K, P, S>
45where
46 S::Output: Project<P>,
47{
48 fn get_mut<Q: Borrow<K>>(&mut self, idx: Q) -> Option<&mut P> {
49 self.data.get_mut(idx).and_then(Project::project_mut)
50 }
51
52 fn get2_mut<Q: Borrow<K>>(&mut self, idx1: Q, idx2: Q) -> (Option<&mut P>, Option<&mut P>) {
53 let (a, b) = self.data.get2_mut(idx1, idx2);
54 (
55 a.and_then(Project::project_mut),
56 b.and_then(Project::project_mut),
57 )
58 }
59
60 fn get3_mut<Q: Borrow<K>>(
61 &mut self,
62 idx1: Q,
63 idx2: Q,
64 idx3: Q,
65 ) -> (Option<&mut P>, Option<&mut P>, Option<&mut P>) {
66 let (a, b, c) = self.data.get3_mut(idx1, idx2, idx3);
67 (
68 a.and_then(Project::project_mut),
69 b.and_then(Project::project_mut),
70 c.and_then(Project::project_mut),
71 )
72 }
73}