1use pui_core::Identifier;
2use typsy::hlist::{Cons, Nil};
3
4use seal::Seal;
5
6use crate::{IdCell, IdentifierExt};
7#[forbid(missing_docs)]
8mod seal {
9 pub trait Seal {
10 fn __internal_find(&self, ptr: *mut ()) -> bool;
11 }
12}
13
14pub trait GetAllMut<I>: Seal {
18 type Output;
20
21 fn get_all_mut(self, ident: I) -> Option<Self::Output>;
24}
25
26impl Seal for Nil {
27 #[inline]
28 fn __internal_find(&self, _: *mut ()) -> bool { false }
29}
30
31impl<T> GetAllMut<T> for Nil {
32 type Output = Nil;
33
34 fn get_all_mut(self, _: T) -> Option<Self::Output> { Some(Self) }
35}
36
37impl<T: ?Sized, R: Seal> Seal for Cons<&T, R> {
38 fn __internal_find(&self, ptr: *mut ()) -> bool {
39 let value = self.value as *const T as *const ();
40 value == ptr || self.rest.__internal_find(ptr)
41 }
42}
43
44impl<'a, T: ?Sized, R, I: ?Sized + Identifier> GetAllMut<&'a mut I> for Cons<&'a IdCell<T, I::Token>, R>
45where
46 R: GetAllMut<&'a mut I>,
47{
48 type Output = Cons<&'a mut T, R::Output>;
49
50 fn get_all_mut(self, ident: &'a mut I) -> Option<Self::Output> {
51 assert!(ident.owns(self.value));
52
53 let ptr = self.value.as_ptr();
54
55 if self.rest.__internal_find(ptr as *mut ()) {
56 return None
57 }
58
59 Some(Cons {
60 value: unsafe { &mut *ptr },
61 rest: self.rest.get_all_mut(ident)?,
62 })
63 }
64}