1use core::marker;
25
26use crate::introspect;
27use crate::private::layout::{
28 data_bits_per_element, ListBuilder, ListReader, PointerBuilder, PointerReader, PrimitiveElement,
29};
30use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter};
31use crate::Result;
32
33#[derive(Clone, Copy)]
34pub struct Owned<T> {
35 marker: marker::PhantomData<T>,
36}
37
38impl<T> introspect::Introspect for Owned<T>
39where
40 T: introspect::Introspect,
41{
42 fn introspect() -> introspect::Type {
43 introspect::Type::list_of(T::introspect())
44 }
45}
46
47impl<T> crate::traits::Owned for Owned<T>
48where
49 T: PrimitiveElement + introspect::Introspect,
50{
51 type Reader<'a> = Reader<'a, T>;
52 type Builder<'a> = Builder<'a, T>;
53}
54
55#[derive(Clone, Copy)]
56pub struct Reader<'a, T>
57where
58 T: PrimitiveElement,
59{
60 marker: marker::PhantomData<T>,
61 reader: ListReader<'a>,
62}
63
64impl<'a, T: PrimitiveElement> Reader<'a, T> {
65 pub fn len(&self) -> u32 {
66 self.reader.len()
67 }
68
69 pub fn is_empty(&self) -> bool {
70 self.len() == 0
71 }
72
73 pub fn iter(self) -> ListIter<Reader<'a, T>, T> {
74 let l = self.len();
75 ListIter::new(self, l)
76 }
77}
78
79impl<'a, T: PrimitiveElement> FromPointerReader<'a> for Reader<'a, T> {
80 fn get_from_pointer(
81 reader: &PointerReader<'a>,
82 default: Option<&'a [crate::Word]>,
83 ) -> Result<Reader<'a, T>> {
84 Ok(Reader {
85 reader: reader.get_list(T::element_size(), default)?,
86 marker: marker::PhantomData,
87 })
88 }
89}
90
91impl<T: PrimitiveElement> IndexMove<u32, T> for Reader<'_, T> {
92 fn index_move(&self, index: u32) -> T {
93 self.get(index)
94 }
95}
96
97impl<T: PrimitiveElement> Reader<'_, T> {
98 pub fn get(&self, index: u32) -> T {
101 assert!(index < self.len());
102 PrimitiveElement::get(&self.reader, index)
103 }
104
105 pub fn try_get(&self, index: u32) -> Option<T> {
108 if index < self.len() {
109 Some(PrimitiveElement::get(&self.reader, index))
110 } else {
111 None
112 }
113 }
114
115 const _CHECK_SLICE: () = check_slice_supported::<T>();
116
117 pub fn as_slice(&self) -> Option<&[T]> {
125 let () = Self::_CHECK_SLICE;
126 if self.reader.get_element_size() == T::element_size() {
127 let bytes = self.reader.into_raw_bytes();
128 let bits_per_element = data_bits_per_element(T::element_size()) as usize;
129 let slice_length = if bits_per_element > 0 {
130 8 * bytes.len() / bits_per_element
131 } else {
132 self.len() as usize
134 };
135 if slice_length == 0 {
136 Some(&[])
137 } else {
138 Some(unsafe {
139 core::slice::from_raw_parts(bytes.as_ptr() as *const T, slice_length)
140 })
141 }
142 } else {
143 None
144 }
145 }
146}
147
148const fn check_slice_supported<T: PrimitiveElement>() {
149 if core::mem::size_of::<T>() > 1 {
150 if !cfg!(target_endian = "little") {
151 panic!("cannot call as_slice on primitive list of multi-byte elements on non-little endian targets");
152 }
153 if cfg!(feature = "unaligned") {
154 panic!("cannot call as_slice on primitive list of multi-byte elements when unaligned feature is enabled");
155 }
156 }
157}
158
159impl<'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T>
160where
161 T: PrimitiveElement,
162{
163 fn into_internal_list_reader(self) -> ListReader<'a> {
164 self.reader
165 }
166}
167
168pub struct Builder<'a, T>
169where
170 T: PrimitiveElement,
171{
172 marker: marker::PhantomData<T>,
173 builder: ListBuilder<'a>,
174}
175
176impl<'a, T> Builder<'a, T>
177where
178 T: PrimitiveElement,
179{
180 pub fn len(&self) -> u32 {
181 self.builder.len()
182 }
183
184 pub fn is_empty(&self) -> bool {
185 self.len() == 0
186 }
187
188 pub fn into_reader(self) -> Reader<'a, T> {
189 Reader {
190 marker: marker::PhantomData,
191 reader: self.builder.into_reader(),
192 }
193 }
194
195 pub fn set(&mut self, index: u32, value: T) {
196 assert!(index < self.len());
197 PrimitiveElement::set(&self.builder, index, value);
198 }
199
200 const _CHECK_SLICE: () = check_slice_supported::<T>();
201
202 pub fn as_slice(&mut self) -> Option<&mut [T]> {
210 let () = Self::_CHECK_SLICE;
211 if self.builder.get_element_size() == T::element_size() {
212 let bytes = self.builder.as_raw_bytes();
213 let bits_per_element = data_bits_per_element(T::element_size()) as usize;
214 let slice_length = if bits_per_element > 0 {
215 8 * bytes.len() / bits_per_element
216 } else {
217 self.len() as usize
219 };
220 if slice_length == 0 {
221 Some(&mut [])
222 } else {
223 Some(unsafe {
224 core::slice::from_raw_parts_mut(bytes.as_mut_ptr() as *mut T, slice_length)
225 })
226 }
227 } else {
228 None
229 }
230 }
231}
232
233impl<'a, T: PrimitiveElement> FromPointerBuilder<'a> for Builder<'a, T> {
234 fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a, T> {
235 Builder {
236 builder: builder.init_list(T::element_size(), size),
237 marker: marker::PhantomData,
238 }
239 }
240 fn get_from_pointer(
241 builder: PointerBuilder<'a>,
242 default: Option<&'a [crate::Word]>,
243 ) -> Result<Builder<'a, T>> {
244 Ok(Builder {
245 builder: builder.get_list(T::element_size(), default)?,
246 marker: marker::PhantomData,
247 })
248 }
249}
250
251impl<T: PrimitiveElement> Builder<'_, T> {
252 pub fn get(&self, index: u32) -> T {
255 assert!(index < self.len());
256 PrimitiveElement::get_from_builder(&self.builder, index)
257 }
258
259 pub fn try_get(&self, index: u32) -> Option<T> {
262 if index < self.len() {
263 Some(PrimitiveElement::get_from_builder(&self.builder, index))
264 } else {
265 None
266 }
267 }
268
269 pub fn reborrow(&mut self) -> Builder<'_, T> {
270 Builder {
271 marker: marker::PhantomData,
272 builder: self.builder.reborrow(),
273 }
274 }
275}
276
277impl<'a, T> crate::traits::SetterInput<Owned<T>> for Reader<'a, T>
278where
279 T: PrimitiveElement,
280{
281 #[inline]
282 fn set_pointer_builder<'b>(
283 mut pointer: PointerBuilder<'b>,
284 value: Reader<'a, T>,
285 canonicalize: bool,
286 ) -> Result<()> {
287 pointer.set_list(&value.reader, canonicalize)
288 }
289}
290
291impl<'a, T> crate::traits::SetterInput<Owned<T>> for &'a [T]
292where
293 T: PrimitiveElement + Copy,
294{
295 #[inline]
296 fn set_pointer_builder<'b>(
297 pointer: PointerBuilder<'b>,
298 value: &'a [T],
299 _canonicalize: bool,
300 ) -> Result<()> {
301 let builder =
302 pointer.init_list(<T as PrimitiveElement>::element_size(), value.len() as u32);
303 for (idx, v) in value.iter().enumerate() {
304 PrimitiveElement::set(&builder, idx as u32, *v)
305 }
306 Ok(())
307 }
308}
309
310impl<'a, T, const N: usize> crate::traits::SetterInput<Owned<T>> for &'a [T; N]
311where
312 T: PrimitiveElement + Copy,
313{
314 #[inline]
315 fn set_pointer_builder<'b>(
316 pointer: PointerBuilder<'b>,
317 value: &'a [T; N],
318 canonicalize: bool,
319 ) -> Result<()> {
320 crate::traits::SetterInput::set_pointer_builder(pointer, &value[..], canonicalize)
321 }
322}
323
324impl<'a, T> ::core::iter::IntoIterator for Reader<'a, T>
325where
326 T: PrimitiveElement,
327{
328 type Item = T;
329 type IntoIter = ListIter<Reader<'a, T>, Self::Item>;
330
331 fn into_iter(self) -> Self::IntoIter {
332 self.iter()
333 }
334}
335
336impl<'a, T: PrimitiveElement + crate::introspect::Introspect> From<Reader<'a, T>>
337 for crate::dynamic_value::Reader<'a>
338{
339 fn from(t: Reader<'a, T>) -> crate::dynamic_value::Reader<'a> {
340 crate::dynamic_value::Reader::List(crate::dynamic_list::Reader::new(
341 t.reader,
342 T::introspect(),
343 ))
344 }
345}
346
347impl<'a, T: PrimitiveElement + crate::introspect::Introspect>
348 crate::dynamic_value::DowncastReader<'a> for Reader<'a, T>
349{
350 fn downcast_reader(v: crate::dynamic_value::Reader<'a>) -> Self {
351 let dl: crate::dynamic_list::Reader = v.downcast();
352 assert!(dl.element_type().loose_equals(T::introspect()));
353 Reader {
354 reader: dl.reader,
355 marker: marker::PhantomData,
356 }
357 }
358}
359
360impl<'a, T: PrimitiveElement + crate::introspect::Introspect> From<Builder<'a, T>>
361 for crate::dynamic_value::Builder<'a>
362{
363 fn from(t: Builder<'a, T>) -> crate::dynamic_value::Builder<'a> {
364 crate::dynamic_value::Builder::List(crate::dynamic_list::Builder::new(
365 t.builder,
366 T::introspect(),
367 ))
368 }
369}
370
371impl<'a, T: PrimitiveElement + crate::introspect::Introspect>
372 crate::dynamic_value::DowncastBuilder<'a> for Builder<'a, T>
373{
374 fn downcast_builder(v: crate::dynamic_value::Builder<'a>) -> Self {
375 let dl: crate::dynamic_list::Builder = v.downcast();
376 assert!(dl.element_type().loose_equals(T::introspect()));
377 Builder {
378 builder: dl.builder,
379 marker: marker::PhantomData,
380 }
381 }
382}
383
384impl<T: Copy + PrimitiveElement + crate::introspect::Introspect> core::fmt::Debug
385 for Reader<'_, T>
386{
387 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
388 core::fmt::Debug::fmt(
389 &::core::convert::Into::<crate::dynamic_value::Reader<'_>>::into(*self),
390 f,
391 )
392 }
393}