1use crate::dynamic_value;
4use crate::introspect::{Type, TypeVariant};
5use crate::private::layout::{self, PrimitiveElement};
6use crate::traits::{IndexMove, ListIter};
7use crate::{Error, ErrorKind, Result};
8
9#[derive(Copy, Clone)]
11pub struct Reader<'a> {
12 pub(crate) reader: layout::ListReader<'a>,
13 pub(crate) element_type: Type,
14}
15
16impl<'a> From<Reader<'a>> for dynamic_value::Reader<'a> {
17 fn from(x: Reader<'a>) -> dynamic_value::Reader<'a> {
18 dynamic_value::Reader::List(x)
19 }
20}
21
22impl<'a> Reader<'a> {
23 pub(crate) fn new(reader: layout::ListReader<'a>, element_type: Type) -> Self {
24 Self {
25 reader,
26 element_type,
27 }
28 }
29
30 pub fn len(&self) -> u32 {
31 self.reader.len()
32 }
33
34 pub fn is_empty(&self) -> bool {
35 self.len() == 0
36 }
37
38 pub fn element_type(&self) -> Type {
39 self.element_type
40 }
41
42 pub fn get(self, index: u32) -> Result<crate::dynamic_value::Reader<'a>> {
43 assert!(index < self.reader.len());
44 match self.element_type.which() {
45 TypeVariant::Void => Ok(dynamic_value::Reader::Void),
46 TypeVariant::Bool => Ok(dynamic_value::Reader::Bool(PrimitiveElement::get(
47 &self.reader,
48 index,
49 ))),
50 TypeVariant::Int8 => Ok(dynamic_value::Reader::Int8(PrimitiveElement::get(
51 &self.reader,
52 index,
53 ))),
54 TypeVariant::Int16 => Ok(dynamic_value::Reader::Int16(PrimitiveElement::get(
55 &self.reader,
56 index,
57 ))),
58 TypeVariant::Int32 => Ok(dynamic_value::Reader::Int32(PrimitiveElement::get(
59 &self.reader,
60 index,
61 ))),
62 TypeVariant::Int64 => Ok(dynamic_value::Reader::Int64(PrimitiveElement::get(
63 &self.reader,
64 index,
65 ))),
66 TypeVariant::UInt8 => Ok(dynamic_value::Reader::UInt8(PrimitiveElement::get(
67 &self.reader,
68 index,
69 ))),
70 TypeVariant::UInt16 => Ok(dynamic_value::Reader::UInt16(PrimitiveElement::get(
71 &self.reader,
72 index,
73 ))),
74 TypeVariant::UInt32 => Ok(dynamic_value::Reader::UInt32(PrimitiveElement::get(
75 &self.reader,
76 index,
77 ))),
78 TypeVariant::UInt64 => Ok(dynamic_value::Reader::UInt64(PrimitiveElement::get(
79 &self.reader,
80 index,
81 ))),
82 TypeVariant::Float32 => Ok(dynamic_value::Reader::Float32(PrimitiveElement::get(
83 &self.reader,
84 index,
85 ))),
86 TypeVariant::Float64 => Ok(dynamic_value::Reader::Float64(PrimitiveElement::get(
87 &self.reader,
88 index,
89 ))),
90 TypeVariant::Enum(e) => Ok(dynamic_value::Enum::new(
91 PrimitiveElement::get(&self.reader, index),
92 e.into(),
93 )
94 .into()),
95 TypeVariant::Text => Ok(dynamic_value::Reader::Text(
96 self.reader.get_pointer_element(index).get_text(None)?,
97 )),
98 TypeVariant::Data => Ok(dynamic_value::Reader::Data(
99 self.reader.get_pointer_element(index).get_data(None)?,
100 )),
101 TypeVariant::List(element_type) => Ok(Reader {
102 reader: self
103 .reader
104 .get_pointer_element(index)
105 .get_list(element_type.expected_element_size(), None)?,
106 element_type,
107 }
108 .into()),
109 TypeVariant::Struct(ss) => {
110 let r = self.reader.get_struct_element(index);
111 Ok(dynamic_value::Reader::Struct(
112 crate::dynamic_struct::Reader::new(r, ss.into()),
113 ))
114 }
115 TypeVariant::AnyPointer => {
116 Ok(crate::any_pointer::Reader::new(self.reader.get_pointer_element(index)).into())
117 }
118 TypeVariant::Capability => {
119 Ok(dynamic_value::Reader::Capability(dynamic_value::Capability))
120 }
121 }
122 }
123
124 pub fn iter(self) -> ListIter<Reader<'a>, Result<dynamic_value::Reader<'a>>> {
125 ListIter::new(self, self.len())
126 }
127}
128
129impl<'a> IndexMove<u32, Result<dynamic_value::Reader<'a>>> for Reader<'a> {
130 fn index_move(&self, index: u32) -> Result<dynamic_value::Reader<'a>> {
131 self.get(index)
132 }
133}
134
135impl<'a> ::core::iter::IntoIterator for Reader<'a> {
136 type Item = Result<dynamic_value::Reader<'a>>;
137 type IntoIter = ListIter<Reader<'a>, Self::Item>;
138
139 fn into_iter(self) -> Self::IntoIter {
140 self.iter()
141 }
142}
143
144pub struct Builder<'a> {
146 pub(crate) builder: layout::ListBuilder<'a>,
147 pub(crate) element_type: Type,
148}
149
150impl<'a> From<Builder<'a>> for dynamic_value::Builder<'a> {
151 fn from(x: Builder<'a>) -> dynamic_value::Builder<'a> {
152 dynamic_value::Builder::List(x)
153 }
154}
155
156impl<'a> Builder<'a> {
157 pub(crate) fn new(builder: layout::ListBuilder<'a>, element_type: Type) -> Self {
158 Self {
159 builder,
160 element_type,
161 }
162 }
163
164 pub fn reborrow(&mut self) -> Builder<'_> {
165 Builder {
166 builder: self.builder.reborrow(),
167 element_type: self.element_type,
168 }
169 }
170
171 pub fn into_reader(self) -> Reader<'a> {
172 Reader {
173 reader: self.builder.into_reader(),
174 element_type: self.element_type,
175 }
176 }
177
178 pub fn len(&self) -> u32 {
179 self.builder.len()
180 }
181
182 pub fn is_empty(&self) -> bool {
183 self.len() == 0
184 }
185
186 pub fn element_type(&self) -> Type {
187 self.element_type
188 }
189
190 pub fn get(self, index: u32) -> Result<dynamic_value::Builder<'a>> {
191 assert!(index < self.builder.len());
192 match self.element_type.which() {
193 TypeVariant::Void => Ok(dynamic_value::Builder::Void),
194 TypeVariant::Bool => Ok(dynamic_value::Builder::Bool(
195 PrimitiveElement::get_from_builder(&self.builder, index),
196 )),
197 TypeVariant::Int8 => Ok(dynamic_value::Builder::Int8(
198 PrimitiveElement::get_from_builder(&self.builder, index),
199 )),
200 TypeVariant::Int16 => Ok(dynamic_value::Builder::Int16(
201 PrimitiveElement::get_from_builder(&self.builder, index),
202 )),
203 TypeVariant::Int32 => Ok(dynamic_value::Builder::Int32(
204 PrimitiveElement::get_from_builder(&self.builder, index),
205 )),
206 TypeVariant::Int64 => Ok(dynamic_value::Builder::Int64(
207 PrimitiveElement::get_from_builder(&self.builder, index),
208 )),
209 TypeVariant::UInt8 => Ok(dynamic_value::Builder::UInt8(
210 PrimitiveElement::get_from_builder(&self.builder, index),
211 )),
212 TypeVariant::UInt16 => Ok(dynamic_value::Builder::UInt16(
213 PrimitiveElement::get_from_builder(&self.builder, index),
214 )),
215 TypeVariant::UInt32 => Ok(dynamic_value::Builder::UInt32(
216 PrimitiveElement::get_from_builder(&self.builder, index),
217 )),
218 TypeVariant::UInt64 => Ok(dynamic_value::Builder::UInt64(
219 PrimitiveElement::get_from_builder(&self.builder, index),
220 )),
221 TypeVariant::Float32 => Ok(dynamic_value::Builder::Float32(
222 PrimitiveElement::get_from_builder(&self.builder, index),
223 )),
224 TypeVariant::Float64 => Ok(dynamic_value::Builder::Float64(
225 PrimitiveElement::get_from_builder(&self.builder, index),
226 )),
227 TypeVariant::Enum(e) => Ok(dynamic_value::Enum::new(
228 PrimitiveElement::get_from_builder(&self.builder, index),
229 e.into(),
230 )
231 .into()),
232 TypeVariant::Text => Ok(dynamic_value::Builder::Text(
233 self.builder.get_pointer_element(index).get_text(None)?,
234 )),
235 TypeVariant::Data => Ok(dynamic_value::Builder::Data(
236 self.builder.get_pointer_element(index).get_data(None)?,
237 )),
238 TypeVariant::List(element_type) => Ok(Builder {
239 builder: self
240 .builder
241 .get_pointer_element(index)
242 .get_list(element_type.expected_element_size(), None)?,
243 element_type,
244 }
245 .into()),
246 TypeVariant::Struct(ss) => {
247 let r = self.builder.get_struct_element(index);
248 Ok(dynamic_value::Builder::Struct(
249 crate::dynamic_struct::Builder::new(r, ss.into()),
250 ))
251 }
252 TypeVariant::AnyPointer => Ok(crate::any_pointer::Builder::new(
253 self.builder.get_pointer_element(index),
254 )
255 .into()),
256 TypeVariant::Capability => Ok(dynamic_value::Builder::Capability(
257 dynamic_value::Capability,
258 )),
259 }
260 }
261
262 pub fn set(&mut self, index: u32, value: dynamic_value::Reader<'_>) -> Result<()> {
263 assert!(index < self.builder.len());
264 match (self.element_type.which(), value) {
265 (TypeVariant::Void, _) => Ok(()),
266 (TypeVariant::Bool, dynamic_value::Reader::Bool(b)) => {
267 PrimitiveElement::set(&self.builder, index, b);
268 Ok(())
269 }
270 (TypeVariant::Int8, dynamic_value::Reader::Int8(x)) => {
271 PrimitiveElement::set(&self.builder, index, x);
272 Ok(())
273 }
274 (TypeVariant::Int16, dynamic_value::Reader::Int16(x)) => {
275 PrimitiveElement::set(&self.builder, index, x);
276 Ok(())
277 }
278 (TypeVariant::Int32, dynamic_value::Reader::Int32(x)) => {
279 PrimitiveElement::set(&self.builder, index, x);
280 Ok(())
281 }
282 (TypeVariant::Int64, dynamic_value::Reader::Int64(x)) => {
283 PrimitiveElement::set(&self.builder, index, x);
284 Ok(())
285 }
286 (TypeVariant::UInt8, dynamic_value::Reader::UInt8(x)) => {
287 PrimitiveElement::set(&self.builder, index, x);
288 Ok(())
289 }
290 (TypeVariant::UInt16, dynamic_value::Reader::UInt16(x)) => {
291 PrimitiveElement::set(&self.builder, index, x);
292 Ok(())
293 }
294 (TypeVariant::UInt32, dynamic_value::Reader::UInt32(x)) => {
295 PrimitiveElement::set(&self.builder, index, x);
296 Ok(())
297 }
298 (TypeVariant::UInt64, dynamic_value::Reader::UInt64(x)) => {
299 PrimitiveElement::set(&self.builder, index, x);
300 Ok(())
301 }
302 (TypeVariant::Float32, dynamic_value::Reader::Float32(x)) => {
303 PrimitiveElement::set(&self.builder, index, x);
304 Ok(())
305 }
306 (TypeVariant::Float64, dynamic_value::Reader::Float64(x)) => {
307 PrimitiveElement::set(&self.builder, index, x);
308 Ok(())
309 }
310 (TypeVariant::Enum(_es), dynamic_value::Reader::Enum(e)) => {
311 PrimitiveElement::set(&self.builder, index, e.get_value());
312 Ok(())
313 }
314 (TypeVariant::Text, dynamic_value::Reader::Text(t)) => {
315 self.builder
316 .reborrow()
317 .get_pointer_element(index)
318 .set_text(t);
319 Ok(())
320 }
321 (TypeVariant::Data, dynamic_value::Reader::Data(d)) => {
322 self.builder
323 .reborrow()
324 .get_pointer_element(index)
325 .set_data(d);
326 Ok(())
327 }
328 (TypeVariant::Struct(ss), dynamic_value::Reader::Struct(s)) => {
329 assert_eq!(ss, s.get_schema().raw);
330 self.builder
331 .reborrow()
332 .get_struct_element(index)
333 .copy_content_from(&s.reader)
334 }
335 (TypeVariant::List(_element_type), dynamic_value::Reader::List(list)) => self
336 .builder
337 .reborrow()
338 .get_pointer_element(index)
339 .set_list(&list.reader, false),
340 (TypeVariant::AnyPointer, _) => {
341 Err(Error::from_kind(ErrorKind::ListAnyPointerNotSupported))
342 }
343 (TypeVariant::Capability, dynamic_value::Reader::Capability(_)) => {
344 Err(Error::from_kind(ErrorKind::ListCapabilityNotSupported))
345 }
346 (_, _) => Err(Error::from_kind(ErrorKind::TypeMismatch)),
347 }
348 }
349
350 pub fn init(self, index: u32, size: u32) -> Result<dynamic_value::Builder<'a>> {
351 assert!(index < self.builder.len());
352 match self.element_type.which() {
353 TypeVariant::Void
354 | TypeVariant::Bool
355 | TypeVariant::Int8
356 | TypeVariant::Int16
357 | TypeVariant::Int32
358 | TypeVariant::Int64
359 | TypeVariant::UInt8
360 | TypeVariant::UInt16
361 | TypeVariant::UInt32
362 | TypeVariant::UInt64
363 | TypeVariant::Float32
364 | TypeVariant::Float64
365 | TypeVariant::Enum(_)
366 | TypeVariant::Struct(_)
367 | TypeVariant::Capability => Err(Error::from_kind(ErrorKind::ExpectedAListOrBlob)),
368 TypeVariant::Text => Ok(self
369 .builder
370 .get_pointer_element(index)
371 .init_text(size)
372 .into()),
373 TypeVariant::Data => Ok(self
374 .builder
375 .get_pointer_element(index)
376 .init_data(size)
377 .into()),
378 TypeVariant::List(inner_element_type) => match inner_element_type.which() {
379 TypeVariant::Struct(rbs) => Ok(Builder::new(
380 self.builder.get_pointer_element(index).init_struct_list(
381 size,
382 crate::dynamic_struct::struct_size_from_schema(rbs.into())?,
383 ),
384 inner_element_type,
385 )
386 .into()),
387 _ => Ok(Builder::new(
388 self.builder
389 .get_pointer_element(index)
390 .init_list(inner_element_type.expected_element_size(), size),
391 inner_element_type,
392 )
393 .into()),
394 },
395 TypeVariant::AnyPointer => Err(Error::from_kind(ErrorKind::ListAnyPointerNotSupported)),
396 }
397 }
398}
399
400impl<'a> crate::traits::SetterInput<crate::any_pointer::Owned> for Reader<'a> {
401 fn set_pointer_builder<'b>(
402 mut pointer: crate::private::layout::PointerBuilder<'b>,
403 value: Reader<'a>,
404 canonicalize: bool,
405 ) -> Result<()> {
406 pointer.set_list(&value.reader, canonicalize)
407 }
408}
409
410impl core::fmt::Debug for Reader<'_> {
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}