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(&crate::dynamic_value::Reader::from(self.reborrow()), f)
302 }
303}