diff --git a/capnp/src/data.rs b/capnp/src/data.rs index 411fc6cf3..23590b518 100644 --- a/capnp/src/data.rs +++ b/capnp/src/data.rs @@ -82,6 +82,21 @@ impl<'a> crate::traits::SetterInput for Reader<'a> { } } +impl<'a, const N: usize> crate::traits::SetterInput for &'a [u8; N] { + #[inline] + fn set_pointer_builder<'b>( + pointer: PointerBuilder<'b>, + value: &'a [u8; N], + canonicalize: bool, + ) -> Result<()> { + as crate::traits::SetterInput>::set_pointer_builder( + pointer, + &value[..], + canonicalize, + ) + } +} + impl<'a> From> for crate::dynamic_value::Reader<'a> { fn from(d: Reader<'a>) -> crate::dynamic_value::Reader<'a> { crate::dynamic_value::Reader::Data(d) diff --git a/capnp/src/data_list.rs b/capnp/src/data_list.rs index 2b037f70b..b3afbbf1e 100644 --- a/capnp/src/data_list.rs +++ b/capnp/src/data_list.rs @@ -22,7 +22,7 @@ //! List of sequences of bytes. use crate::private::layout::*; -use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter}; +use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter, SetterInput}; use crate::Result; #[derive(Copy, Clone)] @@ -134,12 +134,17 @@ impl<'a> Builder<'a> { } } - pub fn set(&mut self, index: u32, value: crate::data::Reader) { + #[inline] + pub fn set(&mut self, index: u32, value: impl SetterInput) { assert!(index < self.len()); - self.builder - .reborrow() - .get_pointer_element(index) - .set_data(value); + SetterInput::set_pointer_builder( + self.builder.reborrow().get_pointer_element(index), + value, + false, + ) + .unwrap() + // The text impls of SetterInput never return an error, so + // the above unwrap() won't panic. } pub fn reborrow(&mut self) -> Builder<'_> { diff --git a/capnpc/src/codegen.rs b/capnpc/src/codegen.rs index a323f0c30..d745efd59 100644 --- a/capnpc/src/codegen.rs +++ b/capnpc/src/codegen.rs @@ -1093,15 +1093,19 @@ fn generate_setter( ) } type_::Data(()) => { - setter_interior.push(Line(format!( - "self.builder.reborrow().get_pointer_field({offset}).set_data(value);" + // The data::Reader impl of SetterInput never fails, so we can unwrap(). + setter_interior.push(Line(fmt!(ctx, + "{capnp}::traits::SetterInput::set_pointer_builder(self.builder.reborrow().get_pointer_field({offset}), value, false).unwrap()" ))); initter_interior.push(Line(format!( "self.builder.get_pointer_field({offset}).init_data(size)" ))); initter_params.push("size: u32"); ( - Some(fmt!(ctx, "{capnp}::data::Reader<'_>")), + Some(fmt!( + ctx, + "impl {capnp}::traits::SetterInput<{capnp}::data::Owned>" + )), Some(fmt!(ctx, "{capnp}::data::Builder<'a>")), ) } @@ -1176,7 +1180,11 @@ fn generate_setter( Line(fmt!(ctx,"{capnp}::traits::SetterInput::set_pointer_builder(self.builder.reborrow().get_pointer_field({offset}), value, false)"))); ( - Some(typ.type_string(ctx, Leaf::Reader("'_"))?), + Some(fmt!( + ctx, + "impl {capnp}::traits::SetterInput<{}>", + typ.type_string(ctx, Leaf::Owned)? + )), Some(typ.type_string(ctx, Leaf::Builder("'a"))?), ) } diff --git a/capnpc/test/test.rs b/capnpc/test/test.rs index 2afb89ec5..873afd401 100644 --- a/capnpc/test/test.rs +++ b/capnpc/test/test.rs @@ -1524,10 +1524,8 @@ mod tests { .allocation_strategy(::capnp::message::AllocationStrategy::FixedSize); let mut message2 = message::Builder::new(builder_options); let mut all_types2 = message2.init_root::>(); - - all_types2 - .set_struct_field(message.get_root_as_reader().unwrap()) - .unwrap(); + let root_reader: test_all_types::Reader<'_> = message.get_root_as_reader().unwrap(); + all_types2.set_struct_field(root_reader).unwrap(); CheckTestMessage::check_test_message(all_types2.reborrow().get_struct_field().unwrap()); let reader = all_types2.into_reader().get_struct_field().unwrap();