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