1use crate::introspect::TypeVariant;
4use crate::private::layout;
5use crate::schema::{Field, StructSchema};
6use crate::schema_capnp::{field, node, value};
7use crate::{dynamic_list, dynamic_value};
8use crate::{Error, ErrorKind, Result};
9
10fn has_discriminant_value(reader: field::Reader) -> bool {
11 reader.get_discriminant_value() != field::NO_DISCRIMINANT
12}
13
14pub(crate) fn struct_size_from_schema(schema: StructSchema) -> Result<layout::StructSize> {
15 if let node::Struct(s) = schema.proto.which()? {
16 Ok(layout::StructSize {
17 data: s.get_data_word_count(),
18 pointers: s.get_pointer_count(),
19 })
20 } else {
21 Err(Error::from_kind(ErrorKind::NotAStruct))
22 }
23}
24
25#[derive(Clone, Copy)]
27pub struct Reader<'a> {
28 pub(crate) reader: layout::StructReader<'a>,
29 pub(crate) schema: StructSchema,
30}
31
32impl<'a> From<Reader<'a>> for dynamic_value::Reader<'a> {
33 fn from(x: Reader<'a>) -> dynamic_value::Reader<'a> {
34 dynamic_value::Reader::Struct(x)
35 }
36}
37
38impl<'a> Reader<'a> {
39 pub fn new(reader: layout::StructReader<'a>, schema: StructSchema) -> Self {
40 Self { reader, schema }
41 }
42
43 pub fn total_size(&self) -> crate::Result<crate::MessageSize> {
44 self.reader.total_size()
45 }
46
47 pub fn get_schema(&self) -> StructSchema {
48 self.schema
49 }
50
51 pub fn get(self, field: Field) -> Result<dynamic_value::Reader<'a>> {
52 assert!(core::ptr::eq(
53 self.schema.raw.generic,
54 field.parent.raw.generic
55 ));
56 let ty = field.get_type();
57 match field.get_proto().which()? {
58 field::Slot(slot) => {
59 let offset = slot.get_offset();
60 let default_value = slot.get_default_value()?;
61
62 match (ty.which(), default_value.which()?) {
63 (TypeVariant::Void, _) => Ok(dynamic_value::Reader::Void),
64 (TypeVariant::Bool, value::Bool(b)) => Ok(dynamic_value::Reader::Bool(
65 self.reader.get_bool_field_mask(offset as usize, b),
66 )),
67 (TypeVariant::Int8, value::Int8(x)) => Ok(dynamic_value::Reader::Int8(
68 self.reader.get_data_field_mask::<i8>(offset as usize, x),
69 )),
70 (TypeVariant::Int16, value::Int16(x)) => Ok(dynamic_value::Reader::Int16(
71 self.reader.get_data_field_mask::<i16>(offset as usize, x),
72 )),
73 (TypeVariant::Int32, value::Int32(x)) => Ok(dynamic_value::Reader::Int32(
74 self.reader.get_data_field_mask::<i32>(offset as usize, x),
75 )),
76 (TypeVariant::Int64, value::Int64(x)) => Ok(dynamic_value::Reader::Int64(
77 self.reader.get_data_field_mask::<i64>(offset as usize, x),
78 )),
79 (TypeVariant::UInt8, value::Uint8(x)) => Ok(dynamic_value::Reader::UInt8(
80 self.reader.get_data_field_mask::<u8>(offset as usize, x),
81 )),
82 (TypeVariant::UInt16, value::Uint16(x)) => Ok(dynamic_value::Reader::UInt16(
83 self.reader.get_data_field_mask::<u16>(offset as usize, x),
84 )),
85 (TypeVariant::UInt32, value::Uint32(x)) => Ok(dynamic_value::Reader::UInt32(
86 self.reader.get_data_field_mask::<u32>(offset as usize, x),
87 )),
88 (TypeVariant::UInt64, value::Uint64(x)) => Ok(dynamic_value::Reader::UInt64(
89 self.reader.get_data_field_mask::<u64>(offset as usize, x),
90 )),
91 (TypeVariant::Float32, value::Float32(x)) => {
92 Ok(dynamic_value::Reader::Float32(
93 self.reader
94 .get_data_field_mask::<f32>(offset as usize, x.to_bits()),
95 ))
96 }
97 (TypeVariant::Float64, value::Float64(x)) => {
98 Ok(dynamic_value::Reader::Float64(
99 self.reader
100 .get_data_field_mask::<f64>(offset as usize, x.to_bits()),
101 ))
102 }
103 (TypeVariant::Enum(schema), value::Enum(d)) => Ok(dynamic_value::Enum::new(
104 self.reader.get_data_field_mask::<u16>(offset as usize, d),
105 schema.into(),
106 )
107 .into()),
108 (TypeVariant::Text, dval) => {
109 let p = self.reader.get_pointer_field(offset as usize);
110 let t1 = if let (true, value::Text(t)) = (p.is_null(), dval) {
113 t?
114 } else {
115 p.get_text(None)?
116 };
117 Ok(dynamic_value::Reader::Text(t1))
118 }
119 (TypeVariant::Data, dval) => {
120 let p = self.reader.get_pointer_field(offset as usize);
121 let d1 = if let (true, value::Data(d)) = (p.is_null(), dval) {
124 d?
125 } else {
126 p.get_data(None)?
127 };
128 Ok(dynamic_value::Reader::Data(d1))
129 }
130 (TypeVariant::Struct(schema), dval) => {
131 let p = self.reader.get_pointer_field(offset as usize);
132 let p1 = if let (true, value::Struct(s)) = (p.is_null(), dval) {
135 s.reader
136 } else {
137 p
138 };
139 let r = p1.get_struct(None)?;
140 Ok(Reader::new(r, schema.into()).into())
141 }
142 (TypeVariant::List(element_type), dval) => {
143 let p = self.reader.get_pointer_field(offset as usize);
144 let p1 = if let (true, value::List(l)) = (p.is_null(), dval) {
147 l.reader
148 } else {
149 p
150 };
151 let l = p1.get_list(element_type.expected_element_size(), None)?;
152 Ok(dynamic_list::Reader::new(l, element_type).into())
153 }
154 (TypeVariant::AnyPointer, value::AnyPointer(a)) => {
155 let p = self.reader.get_pointer_field(offset as usize);
156 let a1 = if p.is_null() {
157 a
158 } else {
159 crate::any_pointer::Reader::new(p)
160 };
161 Ok(dynamic_value::Reader::AnyPointer(a1))
162 }
163 (TypeVariant::Capability, value::Interface(())) => {
164 Ok(dynamic_value::Reader::Capability(dynamic_value::Capability))
165 }
166 _ => Err(Error::from_kind(ErrorKind::FieldAndDefaultMismatch)),
167 }
168 }
169 field::Group(_) => {
170 if let TypeVariant::Struct(schema) = ty.which() {
171 Ok(Reader::new(self.reader, schema.into()).into())
172 } else {
173 Err(Error::from_kind(ErrorKind::GroupFieldButTypeIsNotStruct))
174 }
175 }
176 }
177 }
178
179 pub fn get_named(self, field_name: &str) -> Result<dynamic_value::Reader<'a>> {
181 self.get(self.schema.get_field_by_name(field_name)?)
182 }
183
184 pub fn which(&self) -> Result<Option<Field>> {
187 let node::Struct(st) = self.schema.get_proto().which()? else {
188 return Err(Error::from_kind(ErrorKind::NotAStruct));
189 };
190 if st.get_discriminant_count() == 0 {
191 Ok(None)
192 } else {
193 let discrim = self
194 .reader
195 .get_data_field::<u16>(st.get_discriminant_offset() as usize);
196 self.schema.get_field_by_discriminant(discrim)
197 }
198 }
199
200 pub fn has(&self, field: Field) -> Result<bool> {
204 assert!(core::ptr::eq(
205 self.schema.raw.generic,
206 field.parent.raw.generic
207 ));
208 let proto = field.get_proto();
209 if has_discriminant_value(proto) {
210 let node::Struct(st) = self.schema.get_proto().which()? else {
211 return Err(Error::from_kind(ErrorKind::NotAStruct));
212 };
213
214 let discrim = self
215 .reader
216 .get_data_field::<u16>(st.get_discriminant_offset() as usize);
217 if discrim != proto.get_discriminant_value() {
218 return Ok(false);
220 }
221 }
222 let slot = match proto.which()? {
223 field::Group(_) => return Ok(true),
224 field::Slot(s) => s,
225 };
226 let ty = field.get_type();
227 if ty.is_pointer_type() {
228 Ok(!self
229 .reader
230 .get_pointer_field(slot.get_offset() as usize)
231 .is_null())
232 } else {
233 Ok(true)
234 }
235 }
236
237 pub fn has_named(&self, field_name: &str) -> Result<bool> {
238 let field = self.schema.get_field_by_name(field_name)?;
239 self.has(field)
240 }
241
242 pub fn downcast<T: crate::traits::OwnedStruct>(self) -> T::Reader<'a> {
245 assert!(
246 Into::<crate::introspect::Type>::into(crate::introspect::TypeVariant::Struct(
247 self.schema.raw
248 ))
249 .loose_equals(T::introspect())
250 );
251 self.reader.into()
252 }
253}
254
255pub struct Builder<'a> {
257 pub(crate) builder: layout::StructBuilder<'a>,
258 pub(crate) schema: StructSchema,
259}
260
261impl<'a> From<Builder<'a>> for dynamic_value::Builder<'a> {
262 fn from(x: Builder<'a>) -> dynamic_value::Builder<'a> {
263 dynamic_value::Builder::Struct(x)
264 }
265}
266
267impl<'a> Builder<'a> {
268 pub fn new(builder: layout::StructBuilder<'a>, schema: StructSchema) -> Self {
269 Self { builder, schema }
270 }
271
272 pub fn reborrow(&mut self) -> Builder<'_> {
273 Builder {
274 builder: self.builder.reborrow(),
275 schema: self.schema,
276 }
277 }
278
279 pub fn reborrow_as_reader(&self) -> Reader<'_> {
280 Reader {
281 reader: self.builder.as_reader(),
282 schema: self.schema,
283 }
284 }
285
286 pub fn into_reader(self) -> Reader<'a> {
287 Reader {
288 schema: self.schema,
289 reader: self.builder.into_reader(),
290 }
291 }
292
293 pub fn get_schema(&self) -> StructSchema {
294 self.schema
295 }
296
297 pub fn get(self, field: Field) -> Result<dynamic_value::Builder<'a>> {
298 assert!(core::ptr::eq(
299 self.schema.raw.generic,
300 field.parent.raw.generic
301 ));
302 let ty = field.get_type();
303 match field.get_proto().which()? {
304 field::Slot(slot) => {
305 let offset = slot.get_offset();
306 let default_value = slot.get_default_value()?;
307
308 match (ty.which(), default_value.which()?) {
309 (TypeVariant::Void, _) => Ok(dynamic_value::Builder::Void),
310 (TypeVariant::Bool, value::Bool(b)) => Ok(dynamic_value::Builder::Bool(
311 self.builder.get_bool_field_mask(offset as usize, b),
312 )),
313 (TypeVariant::Int8, value::Int8(x)) => Ok(dynamic_value::Builder::Int8(
314 self.builder.get_data_field_mask::<i8>(offset as usize, x),
315 )),
316 (TypeVariant::Int16, value::Int16(x)) => Ok(dynamic_value::Builder::Int16(
317 self.builder.get_data_field_mask::<i16>(offset as usize, x),
318 )),
319 (TypeVariant::Int32, value::Int32(x)) => Ok(dynamic_value::Builder::Int32(
320 self.builder.get_data_field_mask::<i32>(offset as usize, x),
321 )),
322 (TypeVariant::Int64, value::Int64(x)) => Ok(dynamic_value::Builder::Int64(
323 self.builder.get_data_field_mask::<i64>(offset as usize, x),
324 )),
325 (TypeVariant::UInt8, value::Uint8(x)) => Ok(dynamic_value::Builder::UInt8(
326 self.builder.get_data_field_mask::<u8>(offset as usize, x),
327 )),
328 (TypeVariant::UInt16, value::Uint16(x)) => Ok(dynamic_value::Builder::UInt16(
329 self.builder.get_data_field_mask::<u16>(offset as usize, x),
330 )),
331 (TypeVariant::UInt32, value::Uint32(x)) => Ok(dynamic_value::Builder::UInt32(
332 self.builder.get_data_field_mask::<u32>(offset as usize, x),
333 )),
334 (TypeVariant::UInt64, value::Uint64(x)) => Ok(dynamic_value::Builder::UInt64(
335 self.builder.get_data_field_mask::<u64>(offset as usize, x),
336 )),
337 (TypeVariant::Float32, value::Float32(x)) => {
338 Ok(dynamic_value::Builder::Float32(
339 self.builder
340 .get_data_field_mask::<f32>(offset as usize, x.to_bits()),
341 ))
342 }
343 (TypeVariant::Float64, value::Float64(x)) => {
344 Ok(dynamic_value::Builder::Float64(
345 self.builder
346 .get_data_field_mask::<f64>(offset as usize, x.to_bits()),
347 ))
348 }
349 (TypeVariant::Enum(schema), value::Enum(d)) => Ok(dynamic_value::Enum::new(
350 self.builder.get_data_field_mask::<u16>(offset as usize, d),
351 schema.into(),
352 )
353 .into()),
354 (TypeVariant::Text, dval) => {
355 let mut p = self.builder.get_pointer_field(offset as usize);
356 if p.is_null() {
357 if let value::Text(t) = dval {
360 p.set_text(t?);
361 }
362 }
363 Ok(dynamic_value::Builder::Text(p.get_text(None)?))
364 }
365 (TypeVariant::Data, dval) => {
366 let mut p = self.builder.get_pointer_field(offset as usize);
367 if p.is_null() {
368 if let value::Data(d) = dval {
371 p.set_data(d?);
372 }
373 }
374 Ok(dynamic_value::Builder::Data(p.get_data(None)?))
375 }
376 (TypeVariant::Struct(schema), dval) => {
377 let mut p = self.builder.get_pointer_field(offset as usize);
378 if p.is_null() {
379 if let value::Struct(s) = dval {
382 p.copy_from(s.reader, false)?;
383 }
384 }
385 Ok(Builder::new(
386 p.get_struct(struct_size_from_schema(schema.into())?, None)?,
387 schema.into(),
388 )
389 .into())
390 }
391 (TypeVariant::List(element_type), dval) => {
392 let mut p = self.builder.get_pointer_field(offset as usize);
393 if p.is_null() {
394 if let value::List(l) = dval {
395 p.copy_from(l.reader, false)?;
396 }
397 }
398 let l = if let TypeVariant::Struct(ss) = element_type.which() {
399 p.get_struct_list(struct_size_from_schema(ss.into())?, None)?
400 } else {
401 p.get_list(element_type.expected_element_size(), None)?
402 };
403
404 Ok(dynamic_list::Builder::new(l, element_type).into())
405 }
406 (TypeVariant::AnyPointer, value::AnyPointer(_a)) => {
407 Ok(crate::any_pointer::Builder::new(
409 self.builder.get_pointer_field(offset as usize),
410 )
411 .into())
412 }
413 (TypeVariant::Capability, value::Interface(())) => Ok(
414 dynamic_value::Builder::Capability(dynamic_value::Capability),
415 ),
416 _ => Err(Error::from_kind(ErrorKind::FieldAndDefaultMismatch)),
417 }
418 }
419 field::Group(_) => {
420 if let TypeVariant::Struct(schema) = ty.which() {
421 Ok(Builder::new(self.builder, schema.into()).into())
422 } else {
423 Err(Error::from_kind(ErrorKind::GroupFieldButTypeIsNotStruct))
424 }
425 }
426 }
427 }
428
429 pub fn get_named(self, field_name: &str) -> Result<dynamic_value::Builder<'a>> {
430 let field = self.schema.get_field_by_name(field_name)?;
431 self.get(field)
432 }
433
434 pub fn which(&self) -> Result<Option<Field>> {
435 let node::Struct(st) = self.schema.get_proto().which()? else {
436 return Err(Error::from_kind(ErrorKind::NotAStruct));
437 };
438 if st.get_discriminant_count() == 0 {
439 Ok(None)
440 } else {
441 let discrim = self
442 .builder
443 .get_data_field::<u16>(st.get_discriminant_offset() as usize);
444 self.schema.get_field_by_discriminant(discrim)
445 }
446 }
447
448 pub fn has(&self, field: Field) -> Result<bool> {
449 self.reborrow_as_reader().has(field)
450 }
451
452 pub fn has_named(&self, field_name: &str) -> Result<bool> {
453 let field = self.schema.get_field_by_name(field_name)?;
454 self.has(field)
455 }
456
457 pub fn set(&mut self, field: Field, value: dynamic_value::Reader<'_>) -> Result<()> {
458 assert!(core::ptr::eq(
459 self.schema.raw.generic,
460 field.parent.raw.generic
461 ));
462 self.set_in_union(field)?;
463 let ty = field.get_type();
464 match field.get_proto().which()? {
465 field::Slot(slot) => {
466 let dval = slot.get_default_value()?;
467 let offset = slot.get_offset() as usize;
468 match (ty.which(), value, dval.which()?) {
469 (TypeVariant::Void, _, _) => Ok(()),
470 (TypeVariant::Bool, dynamic_value::Reader::Bool(v), value::Bool(b)) => {
471 self.builder.set_bool_field_mask(offset, v, b);
472 Ok(())
473 }
474 (TypeVariant::Int8, dynamic_value::Reader::Int8(v), value::Int8(d)) => {
475 self.builder.set_data_field_mask::<i8>(offset, v, d);
476 Ok(())
477 }
478 (TypeVariant::Int16, dynamic_value::Reader::Int16(v), value::Int16(d)) => {
479 self.builder.set_data_field_mask::<i16>(offset, v, d);
480 Ok(())
481 }
482 (TypeVariant::Int32, dynamic_value::Reader::Int32(v), value::Int32(d)) => {
483 self.builder.set_data_field_mask::<i32>(offset, v, d);
484 Ok(())
485 }
486 (TypeVariant::Int64, dynamic_value::Reader::Int64(v), value::Int64(d)) => {
487 self.builder.set_data_field_mask::<i64>(offset, v, d);
488 Ok(())
489 }
490 (TypeVariant::UInt8, dynamic_value::Reader::UInt8(v), value::Uint8(d)) => {
491 self.builder.set_data_field_mask::<u8>(offset, v, d);
492 Ok(())
493 }
494 (TypeVariant::UInt16, dynamic_value::Reader::UInt16(v), value::Uint16(d)) => {
495 self.builder.set_data_field_mask::<u16>(offset, v, d);
496 Ok(())
497 }
498 (TypeVariant::UInt32, dynamic_value::Reader::UInt32(v), value::Uint32(d)) => {
499 self.builder.set_data_field_mask::<u32>(offset, v, d);
500 Ok(())
501 }
502 (TypeVariant::UInt64, dynamic_value::Reader::UInt64(v), value::Uint64(d)) => {
503 self.builder.set_data_field_mask::<u64>(offset, v, d);
504 Ok(())
505 }
506 (
507 TypeVariant::Float32,
508 dynamic_value::Reader::Float32(v),
509 value::Float32(d),
510 ) => {
511 self.builder
512 .set_data_field_mask::<f32>(offset, v, d.to_bits());
513 Ok(())
514 }
515 (
516 TypeVariant::Float64,
517 dynamic_value::Reader::Float64(v),
518 value::Float64(d),
519 ) => {
520 self.builder
521 .set_data_field_mask::<f64>(offset, v, d.to_bits());
522 Ok(())
523 }
524 (TypeVariant::Enum(_), dynamic_value::Reader::Enum(ev), value::Enum(d)) => {
525 self.builder
526 .set_data_field_mask::<u16>(offset, ev.get_value(), d);
527 Ok(())
528 }
529 (TypeVariant::Text, dynamic_value::Reader::Text(tv), _) => {
530 let mut p = self.builder.reborrow().get_pointer_field(offset);
531 p.set_text(tv);
532 Ok(())
533 }
534 (TypeVariant::Data, dynamic_value::Reader::Data(v), _) => {
535 let mut p = self.builder.reborrow().get_pointer_field(offset);
536 p.set_data(v);
537 Ok(())
538 }
539 (TypeVariant::List(_), dynamic_value::Reader::List(l), _) => {
540 let mut p = self.builder.reborrow().get_pointer_field(offset);
541 p.set_list(&l.reader, false)
542 }
543 (TypeVariant::Struct(_), dynamic_value::Reader::Struct(v), _) => {
544 let mut p = self.builder.reborrow().get_pointer_field(offset);
545 p.set_struct(&v.reader, false)
546 }
547 (TypeVariant::AnyPointer, _, _) => {
548 let mut target = crate::any_pointer::Builder::new(
549 self.builder.reborrow().get_pointer_field(offset),
550 );
551 match value {
552 dynamic_value::Reader::Text(t) => target.set_as(t),
553 dynamic_value::Reader::Data(t) => {
554 target.set_as::<crate::data::Owned>(t)
555 }
556 dynamic_value::Reader::Struct(s) => target.set_as(s),
557 dynamic_value::Reader::List(l) => target.set_as(l),
558 dynamic_value::Reader::Capability(_) => Err(Error::from_kind(
559 ErrorKind::SettingDynamicCapabilitiesIsUnsupported,
560 )),
561 _ => Err(Error::from_kind(
562 ErrorKind::CannotSetAnyPointerFieldToAPrimitiveValue,
563 )),
564 }
565 }
566 (TypeVariant::Capability, _, _) => Err(Error::from_kind(
567 ErrorKind::SettingDynamicCapabilitiesIsUnsupported,
568 )),
569 _ => Err(Error::from_kind(ErrorKind::TypeMismatch)),
570 }
571 }
572 field::Group(_group) => {
573 let dynamic_value::Reader::Struct(src) = value else {
574 return Err(Error::from_kind(ErrorKind::NotAStruct));
575 };
576 let dynamic_value::Builder::Struct(mut dst) = self.reborrow().init(field)? else {
577 return Err(Error::from_kind(ErrorKind::NotAStruct));
578 };
579 if let Some(union_field) = src.which()? {
580 dst.set(union_field, src.get(union_field)?)?;
581 }
582
583 let non_union_fields = src.schema.get_non_union_fields()?;
584 for idx in 0..non_union_fields.len() {
585 let field = non_union_fields.get(idx);
586 if src.has(field)? {
587 dst.set(field, src.get(field)?)?;
588 }
589 }
590 Ok(())
591 }
592 }
593 }
594
595 pub fn set_named(&mut self, field_name: &str, value: dynamic_value::Reader<'_>) -> Result<()> {
596 let field = self.schema.get_field_by_name(field_name)?;
597 self.set(field, value)
598 }
599
600 pub fn init(mut self, field: Field) -> Result<dynamic_value::Builder<'a>> {
601 assert!(core::ptr::eq(
602 self.schema.raw.generic,
603 field.parent.raw.generic
604 ));
605 self.set_in_union(field)?;
606 let ty = field.get_type();
607 match field.get_proto().which()? {
608 field::Slot(slot) => {
609 let offset = slot.get_offset() as usize;
610 match ty.which() {
611 TypeVariant::Struct(ss) => Ok(Builder {
612 schema: ss.into(),
613 builder: self
614 .builder
615 .get_pointer_field(offset)
616 .init_struct(struct_size_from_schema(ss.into())?),
617 }
618 .into()),
619 TypeVariant::AnyPointer => {
620 let mut p = self.builder.get_pointer_field(offset);
621 p.clear();
622 Ok(crate::any_pointer::Builder::new(p).into())
623 }
624 _ => Err(Error::from_kind(
625 ErrorKind::InitIsOnlyValidForStructAndAnyPointerFields,
626 )),
627 }
628 }
629 field::Group(_) => {
630 self.clear(field)?;
631 let TypeVariant::Struct(schema) = ty.which() else {
632 return Err(Error::from_kind(ErrorKind::NotAStruct));
633 };
634 Ok((Builder::new(self.builder, schema.into())).into())
635 }
636 }
637 }
638
639 pub fn init_named(self, field_name: &str) -> Result<dynamic_value::Builder<'a>> {
640 let field = self.schema.get_field_by_name(field_name)?;
641 self.init(field)
642 }
643
644 pub fn initn(mut self, field: Field, size: u32) -> Result<dynamic_value::Builder<'a>> {
645 assert!(core::ptr::eq(
646 self.schema.raw.generic,
647 field.parent.raw.generic
648 ));
649 self.set_in_union(field)?;
650 let ty = field.get_type();
651 match field.get_proto().which()? {
652 field::Slot(slot) => {
653 let offset = slot.get_offset() as usize;
654 match ty.which() {
655 TypeVariant::List(element_type) => match element_type.which() {
656 TypeVariant::Struct(ss) => Ok(dynamic_list::Builder::new(
657 self.builder
658 .get_pointer_field(offset)
659 .init_struct_list(size, struct_size_from_schema(ss.into())?),
660 element_type,
661 )
662 .into()),
663 _ => Ok(dynamic_list::Builder::new(
664 self.builder
665 .get_pointer_field(offset)
666 .init_list(element_type.expected_element_size(), size),
667 element_type,
668 )
669 .into()),
670 },
671 TypeVariant::Text => Ok(self
672 .builder
673 .get_pointer_field(offset)
674 .init_text(size)
675 .into()),
676 TypeVariant::Data => Ok(self
677 .builder
678 .get_pointer_field(offset)
679 .init_data(size)
680 .into()),
681
682 _ => Err(Error::from_kind(
683 ErrorKind::InitnIsOnlyValidForListTextOrDataFields,
684 )),
685 }
686 }
687 field::Group(_) => Err(Error::from_kind(
688 ErrorKind::InitnIsOnlyValidForListTextOrDataFields,
689 )),
690 }
691 }
692
693 pub fn initn_named(self, field_name: &str, size: u32) -> Result<dynamic_value::Builder<'a>> {
694 let field = self.schema.get_field_by_name(field_name)?;
695 self.initn(field, size)
696 }
697
698 pub fn clear(&mut self, field: Field) -> Result<()> {
701 assert!(core::ptr::eq(
702 self.schema.raw.generic,
703 field.parent.raw.generic
704 ));
705 self.set_in_union(field)?;
706 let ty = field.get_type();
707 match field.get_proto().which()? {
708 field::Slot(slot) => {
709 let offset = slot.get_offset() as usize;
710 match ty.which() {
711 TypeVariant::Void => Ok(()),
712 TypeVariant::Bool => {
713 self.builder.set_bool_field(offset, false);
714 Ok(())
715 }
716 TypeVariant::Int8 => {
717 self.builder.set_data_field::<i8>(offset, 0);
718 Ok(())
719 }
720 TypeVariant::Int16 => {
721 self.builder.set_data_field::<i16>(offset, 0);
722 Ok(())
723 }
724 TypeVariant::Int32 => {
725 self.builder.set_data_field::<i32>(offset, 0);
726 Ok(())
727 }
728 TypeVariant::Int64 => {
729 self.builder.set_data_field::<i64>(offset, 0);
730 Ok(())
731 }
732 TypeVariant::UInt8 => {
733 self.builder.set_data_field::<u8>(offset, 0);
734 Ok(())
735 }
736 TypeVariant::UInt16 => {
737 self.builder.set_data_field::<u16>(offset, 0);
738 Ok(())
739 }
740 TypeVariant::UInt32 => {
741 self.builder.set_data_field::<u32>(offset, 0);
742 Ok(())
743 }
744 TypeVariant::UInt64 => {
745 self.builder.set_data_field::<u64>(offset, 0);
746 Ok(())
747 }
748 TypeVariant::Float32 => {
749 self.builder.set_data_field::<f32>(offset, 0f32);
750 Ok(())
751 }
752 TypeVariant::Float64 => {
753 self.builder.set_data_field::<f64>(offset, 0f64);
754 Ok(())
755 }
756 TypeVariant::Enum(_) => {
757 self.builder.set_data_field::<u16>(offset, 0);
758 Ok(())
759 }
760 TypeVariant::Text
761 | TypeVariant::Data
762 | TypeVariant::Struct(_)
763 | TypeVariant::List(_)
764 | TypeVariant::AnyPointer
765 | TypeVariant::Capability => {
766 self.builder.reborrow().get_pointer_field(offset).clear();
767 Ok(())
768 }
769 }
770 }
771 field::Group(_) => {
772 let TypeVariant::Struct(schema) = ty.which() else {
773 return Err(Error::from_kind(ErrorKind::NotAStruct));
774 };
775 let mut group = Builder::new(self.builder.reborrow(), schema.into());
776
777 if let Some(union_field) = group.schema.get_field_by_discriminant(0)? {
780 group.clear(union_field)?;
781 }
782
783 let non_union_fields = group.schema.get_non_union_fields()?;
784 for idx in 0..non_union_fields.len() {
785 group.clear(non_union_fields.get(idx))?;
786 }
787 Ok(())
788 }
789 }
790 }
791
792 pub fn clear_named(&mut self, field_name: &str) -> Result<()> {
793 let field = self.schema.get_field_by_name(field_name)?;
794 self.clear(field)
795 }
796
797 fn set_in_union(&mut self, field: Field) -> Result<()> {
798 if has_discriminant_value(field.get_proto()) {
799 let node::Struct(st) = self.schema.get_proto().which()? else {
800 return Err(Error::from_kind(ErrorKind::NotAStruct));
801 };
802 self.builder.set_data_field::<u16>(
803 st.get_discriminant_offset() as usize,
804 field.get_proto().get_discriminant_value(),
805 );
806 }
807 Ok(())
808 }
809
810 pub fn downcast<T: crate::traits::OwnedStruct>(self) -> T::Builder<'a> {
813 assert!(
814 Into::<crate::introspect::Type>::into(crate::introspect::TypeVariant::Struct(
815 self.schema.raw
816 ))
817 .loose_equals(T::introspect())
818 );
819 self.builder.into()
820 }
821}
822
823impl<'a> crate::traits::SetterInput<crate::any_pointer::Owned> for Reader<'a> {
824 fn set_pointer_builder<'b>(
825 mut pointer: crate::private::layout::PointerBuilder<'b>,
826 value: Reader<'a>,
827 canonicalize: bool,
828 ) -> Result<()> {
829 pointer.set_struct(&value.reader, canonicalize)
830 }
831}
832
833impl core::fmt::Debug for Reader<'_> {
834 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
835 core::fmt::Debug::fmt(
836 &::core::convert::Into::<crate::dynamic_value::Reader<'_>>::into(*self),
837 f,
838 )
839 }
840}