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