1#![cfg(feature = "alloc")]
23
24use core::marker::PhantomData;
25
26use crate::capability::FromClientHook;
27use crate::private::capability::ClientHook;
28use crate::private::layout::{ListBuilder, ListReader, Pointer, PointerBuilder, PointerReader};
29use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter};
30use crate::Result;
31
32#[derive(Copy, Clone)]
33pub struct Owned<T>
34where
35    T: FromClientHook,
36{
37    marker: PhantomData<T>,
38}
39
40impl<T> crate::introspect::Introspect for Owned<T>
41where
42    T: FromClientHook,
43{
44    fn introspect() -> crate::introspect::Type {
45        crate::introspect::Type::list_of(crate::introspect::TypeVariant::Capability.into())
46    }
47}
48
49impl<T> crate::traits::Owned for Owned<T>
50where
51    T: FromClientHook,
52{
53    type Reader<'a> = Reader<'a, T>;
54    type Builder<'a> = Builder<'a, T>;
55}
56
57pub struct Reader<'a, T>
58where
59    T: FromClientHook,
60{
61    marker: PhantomData<T>,
62    reader: ListReader<'a>,
63}
64
65impl<'a, T> Clone for Reader<'a, T>
66where
67    T: FromClientHook,
68{
69    fn clone(&self) -> Reader<'a, T> {
70        *self
71    }
72}
73impl<T> Copy for Reader<'_, T> where T: FromClientHook {}
74
75impl<'a, T> Reader<'a, T>
76where
77    T: FromClientHook,
78{
79    pub fn len(&self) -> u32 {
80        self.reader.len()
81    }
82
83    pub fn is_empty(&self) -> bool {
84        self.len() == 0
85    }
86
87    pub fn iter(self) -> ListIter<Reader<'a, T>, Result<T>> {
88        ListIter::new(self, self.len())
89    }
90}
91
92impl<T> Reader<'_, T>
93where
94    T: FromClientHook,
95{
96    pub fn reborrow(&self) -> Reader<'_, T> {
97        Reader {
98            reader: self.reader,
99            marker: PhantomData,
100        }
101    }
102}
103
104impl<'a, T> FromPointerReader<'a> for Reader<'a, T>
105where
106    T: FromClientHook,
107{
108    fn get_from_pointer(
109        reader: &PointerReader<'a>,
110        default: Option<&'a [crate::Word]>,
111    ) -> Result<Reader<'a, T>> {
112        Ok(Reader {
113            reader: reader.get_list(Pointer, default)?,
114            marker: PhantomData,
115        })
116    }
117}
118
119impl<T> Reader<'_, T>
120where
121    T: FromClientHook,
122{
123    pub fn get(self, index: u32) -> Result<T> {
126        assert!(index < self.len());
127        Ok(FromClientHook::new(
128            self.reader.get_pointer_element(index).get_capability()?,
129        ))
130    }
131
132    pub fn try_get(self, index: u32) -> Option<Result<T>> {
135        if index < self.len() {
136            Some(
137                self.reader
138                    .get_pointer_element(index)
139                    .get_capability()
140                    .map(FromClientHook::new),
141            )
142        } else {
143            None
144        }
145    }
146}
147
148impl<T> IndexMove<u32, Result<T>> for Reader<'_, T>
149where
150    T: FromClientHook,
151{
152    fn index_move(&self, index: u32) -> Result<T> {
153        self.get(index)
154    }
155}
156
157pub struct Builder<'a, T>
158where
159    T: FromClientHook,
160{
161    marker: PhantomData<T>,
162    builder: ListBuilder<'a>,
163}
164
165impl<'a, T> Builder<'a, T>
166where
167    T: FromClientHook,
168{
169    pub fn len(&self) -> u32 {
170        self.builder.len()
171    }
172
173    pub fn is_empty(&self) -> bool {
174        self.len() == 0
175    }
176
177    pub fn into_reader(self) -> Reader<'a, T> {
178        Reader {
179            marker: PhantomData,
180            reader: self.builder.into_reader(),
181        }
182    }
183
184    pub fn set(&mut self, index: u32, value: alloc::boxed::Box<dyn ClientHook>) {
185        assert!(index < self.len());
186        self.builder
187            .reborrow()
188            .get_pointer_element(index)
189            .set_capability(value);
190    }
191}
192
193impl<T> Builder<'_, T>
194where
195    T: FromClientHook,
196{
197    pub fn reborrow(&mut self) -> Builder<'_, T> {
198        Builder {
199            builder: self.builder.reborrow(),
200            marker: PhantomData,
201        }
202    }
203}
204
205impl<'a, T> FromPointerBuilder<'a> for Builder<'a, T>
206where
207    T: FromClientHook,
208{
209    fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a, T> {
210        Builder {
211            marker: PhantomData,
212            builder: builder.init_list(Pointer, size),
213        }
214    }
215    fn get_from_pointer(
216        builder: PointerBuilder<'a>,
217        default: Option<&'a [crate::Word]>,
218    ) -> Result<Builder<'a, T>> {
219        Ok(Builder {
220            marker: PhantomData,
221            builder: builder.get_list(Pointer, default)?,
222        })
223    }
224}
225
226impl<T> Builder<'_, T>
227where
228    T: FromClientHook,
229{
230    pub fn get(self, index: u32) -> Result<T> {
233        assert!(index < self.len());
234        Ok(FromClientHook::new(
235            self.builder.get_pointer_element(index).get_capability()?,
236        ))
237    }
238
239    pub fn try_get(self, index: u32) -> Option<Result<T>> {
242        if index < self.len() {
243            Some(
244                self.builder
245                    .get_pointer_element(index)
246                    .get_capability()
247                    .map(FromClientHook::new),
248            )
249        } else {
250            None
251        }
252    }
253}
254
255impl<'a, T> crate::traits::SetterInput<Owned<T>> for Reader<'a, T>
256where
257    T: FromClientHook,
258{
259    #[inline]
260    fn set_pointer_builder<'b>(
261        mut pointer: crate::private::layout::PointerBuilder<'b>,
262        value: Reader<'a, T>,
263        canonicalize: bool,
264    ) -> Result<()> {
265        pointer.set_list(&value.reader, canonicalize)
266    }
267}
268
269impl<'a, T> ::core::iter::IntoIterator for Reader<'a, T>
270where
271    T: FromClientHook,
272{
273    type Item = Result<T>;
274    type IntoIter = ListIter<Reader<'a, T>, Self::Item>;
275
276    fn into_iter(self) -> Self::IntoIter {
277        self.iter()
278    }
279}
280
281impl<'a, T: FromClientHook> From<Reader<'a, T>> for crate::dynamic_value::Reader<'a> {
282    fn from(t: Reader<'a, T>) -> crate::dynamic_value::Reader<'a> {
283        crate::dynamic_value::Reader::List(crate::dynamic_list::Reader::new(
284            t.reader,
285            crate::introspect::TypeVariant::Capability.into(),
286        ))
287    }
288}
289
290impl<'a, T: FromClientHook> From<Builder<'a, T>> for crate::dynamic_value::Builder<'a> {
291    fn from(t: Builder<'a, T>) -> crate::dynamic_value::Builder<'a> {
292        crate::dynamic_value::Builder::List(crate::dynamic_list::Builder::new(
293            t.builder,
294            crate::introspect::TypeVariant::Capability.into(),
295        ))
296    }
297}
298
299impl<T: FromClientHook> core::fmt::Debug for Reader<'_, T> {
300    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
301        core::fmt::Debug::fmt(
302            &::core::convert::Into::<crate::dynamic_value::Reader<'_>>::into(self.reborrow()),
303            f,
304        )
305    }
306}