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