From 8a432b2cc5d1f7d4e57db0356db60b5e2b6b2549 Mon Sep 17 00:00:00 2001 From: Gijs de Jong Date: Fri, 1 May 2026 14:21:17 +0200 Subject: [PATCH 1/3] Support upstream cdr-encoding zero-copy changes --- examples/async_shapes_demo/main.rs | 2 +- examples/shapes_demo/main.rs | 2 +- examples/shapes_demo_mio_08/main.rs | 2 +- src/dds/adapters.rs | 72 +++++++++++++++++----------- src/dds/no_key/simpledatareader.rs | 4 +- src/dds/no_key/wrappers.rs | 16 +++---- src/dds/with_key/simpledatareader.rs | 16 +++---- src/discovery/discovery.rs | 4 +- src/lib.rs | 4 +- src/serialization.rs | 4 +- src/serialization/cdr_adapters.rs | 34 ++++++------- src/serialization/pl_cdr_adapters.rs | 8 ++-- 12 files changed, 88 insertions(+), 80 deletions(-) diff --git a/examples/async_shapes_demo/main.rs b/examples/async_shapes_demo/main.rs index b45e71f4..863ba2be 100644 --- a/examples/async_shapes_demo/main.rs +++ b/examples/async_shapes_demo/main.rs @@ -19,7 +19,7 @@ use rustdds::{ TopicDescription, TopicKind, }; use rustdds::policy::{Deadline, Durability, History, Reliability}; /* import all QoS - * policies directly */ + * policies directly */ use serde::{Deserialize, Serialize}; use clap::{Arg, ArgMatches, Command}; // command line argument processing use rand::prelude::*; diff --git a/examples/shapes_demo/main.rs b/examples/shapes_demo/main.rs index 83b36c1d..0cb842d4 100644 --- a/examples/shapes_demo/main.rs +++ b/examples/shapes_demo/main.rs @@ -21,7 +21,7 @@ use rustdds::{ StatusEvented, TopicDescription, TopicKind, }; use rustdds::policy::{Deadline, Durability, History, Reliability}; /* import all QoS - * policies directly */ + * policies directly */ use serde::{Deserialize, Serialize}; use clap::{Arg, ArgMatches, Command}; // command line argument processing use mio_06::{Events, Poll, PollOpt, Ready, Token}; // polling diff --git a/examples/shapes_demo_mio_08/main.rs b/examples/shapes_demo_mio_08/main.rs index cbf1948b..e30b58e4 100644 --- a/examples/shapes_demo_mio_08/main.rs +++ b/examples/shapes_demo_mio_08/main.rs @@ -26,7 +26,7 @@ use rustdds::{ TopicDescription, TopicKind, }; use rustdds::policy::{Deadline, Durability, History, Reliability}; /* import all QoS - * policies directly */ + * policies directly */ use serde::{Deserialize, Serialize}; use clap::{Arg, ArgMatches, Command}; // command line argument processing use mio_08::{Events, Interest, Poll, Token}; // non-blocking i/o polling diff --git a/src/dds/adapters.rs b/src/dds/adapters.rs index 3e1032d7..a8f847b1 100644 --- a/src/dds/adapters.rs +++ b/src/dds/adapters.rs @@ -125,13 +125,17 @@ pub mod no_key { /// /// `encoding` must be something given by `supported_encodings()`, or /// implementation may fail with Err or `panic!()`. - fn from_bytes_with( - input_bytes: &[u8], + /// + /// The input slice's lifetime is tied to the deserialization lifetime + /// `'de`, so adapters that produce borrowed data (zero-copy) are + /// supported. + fn from_bytes_with<'de, S>( + input_bytes: &'de [u8], encoding: RepresentationIdentifier, decoder: S, ) -> Result where - S: Decode, + S: Decode<'de, Self::Decoded>, { decoder .decode_bytes(input_bytes, encoding) @@ -144,7 +148,10 @@ pub mod no_key { /// /// Only usable if the adapter has a default decoder, i.e. implements /// `DefaultDecoder`. - fn from_bytes(input_bytes: &[u8], encoding: RepresentationIdentifier) -> Result + fn from_bytes<'de>( + input_bytes: &'de [u8], + encoding: RepresentationIdentifier, + ) -> Result where Self: DefaultDecoder, { @@ -158,8 +165,9 @@ pub mod no_key { /// Type of the default decoder. /// /// The default decoder needs to be clonable to be usable for async stream - /// creation (as it's needed multiple times). - type Decoder: Decode + Clone; + /// creation (as it's needed multiple times). It must work for any input + /// lifetime, hence the higher-ranked `for<'de>` bound. + type Decoder: for<'de> Decode<'de, Self::Decoded, Error = Self::Error> + Clone; /// The default decoder value. /// @@ -168,21 +176,23 @@ pub mod no_key { const DECODER: Self::Decoder; } - /// The trait `Decode` defines a decoder object that produced a value of type - /// `Dec` from a slice of bytes and a [`RepresentationIdentifier`]. + /// The trait `Decode` defines a decoder object that produces a value of type + /// `Decoded` from a slice of bytes and a [`RepresentationIdentifier`]. /// - /// Note - /// that `Decoded` maps to associated type `Decoded` in - /// `DeserializerAdapter` , not `D`. - pub trait Decode { + /// Note that `Decoded` maps to associated type `Decoded` in + /// `DeserializerAdapter`, not `D`. + /// + /// The lifetime `'de` is the deserialization lifetime: the returned + /// `Decoded` value may borrow from `input_bytes` for `'de`. + pub trait Decode<'de, Decoded> { /// The decoding error type returned by [`Self::decode_bytes`]. type Error: std::error::Error; - /// Tries to decode the given byte slice to a value of type `D` using the - /// given encoding. + /// Tries to decode the given byte slice to a value of type `Decoded` + /// using the given encoding. fn decode_bytes( self, - input_bytes: &[u8], + input_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result; } @@ -242,13 +252,13 @@ pub mod with_key { /// /// `encoding` must be something given by `supported_encodings()`, or /// implementation may fail with Err or `panic!()`. - fn key_from_bytes_with( - input_bytes: &[u8], + fn key_from_bytes_with<'de, S>( + input_bytes: &'de [u8], encoding: RepresentationIdentifier, decoder: S, ) -> Result where - S: Decode, + S: Decode<'de, Self::Decoded, Self::DecodedKey>, { decoder .decode_key_bytes(input_bytes, encoding) @@ -260,8 +270,8 @@ pub mod with_key { /// implementation may fail with Err or `panic!()`. /// /// Only usable if the adapter has a default decoder. - fn key_from_bytes( - input_bytes: &[u8], + fn key_from_bytes<'de>( + input_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result where @@ -280,8 +290,9 @@ pub mod with_key { /// Type of the default decoder. /// /// The default decoder needs to be clonable to be usable for async stream - /// creation (as it's needed multiple times). - type Decoder: Decode + Clone; + /// creation (as it's needed multiple times). It must work for any input + /// lifetime, hence the higher-ranked `for<'de>` bound. + type Decoder: for<'de> Decode<'de, Self::Decoded, Self::DecodedKey, Error = Self::Error> + Clone; /// The default decoder value. /// @@ -290,15 +301,18 @@ pub mod with_key { const DECODER: Self::Decoder; } - /// Decodes a value of type `Dec` from a slice of bytes and a - /// [`RepresentationIdentifier`]. Note that `Dec` maps to associated type - /// `Decoded` in `DeserializerAdapter` , not `D`. - pub trait Decode: no_key::Decode { - /// Tries to decode the given byte slice to a value of type `D` using the - /// given encoding. + /// Decodes a value of type `Dec` (or its key `DecKey`) from a slice of + /// bytes and a [`RepresentationIdentifier`]. Note that `Dec` maps to + /// associated type `Decoded` in `DeserializerAdapter`, not `D`. + /// + /// The lifetime `'de` is the deserialization lifetime: the returned key + /// may borrow from `input_key_bytes` for `'de`. + pub trait Decode<'de, Dec, DecKey>: no_key::Decode<'de, Dec> { + /// Tries to decode the given byte slice to a value of type `DecKey` + /// using the given encoding. fn decode_key_bytes( self, - input_key_bytes: &[u8], + input_key_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result; } diff --git a/src/dds/no_key/simpledatareader.rs b/src/dds/no_key/simpledatareader.rs index 0825ad71..f695e97a 100644 --- a/src/dds/no_key/simpledatareader.rs +++ b/src/dds/no_key/simpledatareader.rs @@ -64,7 +64,7 @@ where pub fn try_take_one_with(&self, decoder: S) -> ReadResult>> where - S: Decode + Clone, + S: for<'de> Decode<'de, DA::Decoded, Error = DA::Error> + Clone, { match self .keyed_simpledatareader @@ -101,7 +101,7 @@ where decoder: S, ) -> impl FusedStream>> + 'a where - S: Decode + Clone + 'a, + S: for<'de> Decode<'de, DA::Decoded, Error = DA::Error> + Clone + 'a, { self .keyed_simpledatareader diff --git a/src/dds/no_key/wrappers.rs b/src/dds/no_key/wrappers.rs index 6245ca5a..7e426744 100644 --- a/src/dds/no_key/wrappers.rs +++ b/src/dds/no_key/wrappers.rs @@ -2,9 +2,7 @@ use std::{marker::PhantomData, ops::Deref}; use bytes::Bytes; -use crate::{ - dds::adapters::*, messages::submessages::submessages::RepresentationIdentifier, Keyed, -}; +use crate::{dds::adapters::*, messages::submessages::submessages::RepresentationIdentifier, Keyed}; // This wrapper is used to convert NO_KEY types to WITH_KEY // * inside the wrapper there is a NO_KEY type @@ -144,15 +142,15 @@ impl DecodeWrapper { // re-implement no_key::Decode for the wrapper also. Wrapped type // already does it for us. -impl no_key::Decode for DecodeWrapper +impl<'de, Decoded, NoKeyDecode> no_key::Decode<'de, Decoded> for DecodeWrapper where - NoKeyDecode: no_key::Decode, + NoKeyDecode: no_key::Decode<'de, Decoded>, { type Error = NoKeyDecode::Error; fn decode_bytes( self, - input_bytes: &[u8], + input_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result { self.no_key.decode_bytes(input_bytes, encoding) @@ -162,13 +160,13 @@ where // implement with_key::Decode for the wrapper. // The key has type `()`, so the decoded value is always `()` regardless of the // input bytes. -impl with_key::Decode for DecodeWrapper +impl<'de, Decoded, NoKeyDecode> with_key::Decode<'de, Decoded, ()> for DecodeWrapper where - NoKeyDecode: no_key::Decode, + NoKeyDecode: no_key::Decode<'de, Decoded>, { fn decode_key_bytes( self, - _input_key_bytes: &[u8], + _input_key_bytes: &'de [u8], _encoding: RepresentationIdentifier, ) -> Result<(), Self::Error> { Ok(()) diff --git a/src/dds/with_key/simpledatareader.rs b/src/dds/with_key/simpledatareader.rs index 0c6c0e4e..6bf345ba 100644 --- a/src/dds/with_key/simpledatareader.rs +++ b/src/dds/with_key/simpledatareader.rs @@ -234,7 +234,7 @@ where decoder: S, ) -> ReadResult> where - S: Decode, + S: for<'de> Decode<'de, DA::Decoded, DA::DecodedKey, Error = DA::Error>, { match cc.data_value { DDSData::Data { @@ -342,7 +342,7 @@ where #[allow(clippy::needless_pass_by_value)] pub fn try_take_one_with(&self, decoder: S) -> ReadResult>> where - S: Decode + Clone, + S: for<'de> Decode<'de, DA::Decoded, DA::DecodedKey, Error = DA::Error> + Clone, { let is_reliable = matches!( self.qos_policy.reliability(), @@ -414,14 +414,14 @@ where where DA: DefaultDecoder, DA::Decoder: Clone, - S: Decode, + S: for<'de> Decode<'de, DA::Decoded, DA::DecodedKey, Error = DA::Error>, { Self::as_async_stream_with(self, DA::DECODER) } pub fn as_async_stream_with(&self, decoder: S) -> SimpleDataReaderStream<'_, D, S, DA> where - S: Decode + Clone, + S: for<'de> Decode<'de, DA::Decoded, DA::DecodedKey, Error = DA::Error> + Clone, { SimpleDataReaderStream { simple_datareader: self, @@ -553,7 +553,7 @@ where pub struct SimpleDataReaderStream< 'a, D: Keyed + 'static, - S: Decode, + S: for<'de> Decode<'de, DA::Decoded, DA::DecodedKey, Error = DA::Error>, DA: DeserializerAdapter + 'static = CDRDeserializerAdapter, > { simple_datareader: &'a SimpleDataReader, @@ -568,7 +568,7 @@ impl Unpin for SimpleDataReaderStream<'_, D, S, DA> where D: Keyed + 'static, DA: DeserializerAdapter, - S: Decode + Unpin, + S: for<'de> Decode<'de, DA::Decoded, DA::DecodedKey, Error = DA::Error> + Unpin, { } @@ -576,7 +576,7 @@ impl Stream for SimpleDataReaderStream<'_, D, S, DA> where D: Keyed + 'static, DA: DeserializerAdapter, - S: Decode + Clone, + S: for<'de> Decode<'de, DA::Decoded, DA::DecodedKey, Error = DA::Error> + Clone, { type Item = ReadResult>; @@ -633,7 +633,7 @@ impl FusedStream for SimpleDataReaderStream<'_, D, S, DA> where D: Keyed + 'static, DA: DeserializerAdapter, - S: Decode + Clone, + S: for<'de> Decode<'de, DA::Decoded, DA::DecodedKey, Error = DA::Error> + Clone, { fn is_terminated(&self) -> bool { false // Never terminate. This means it is always valid to call poll_next(). diff --git a/src/discovery/discovery.rs b/src/discovery/discovery.rs index b833c493..b88c2cc6 100644 --- a/src/discovery/discovery.rs +++ b/src/discovery/discovery.rs @@ -135,9 +135,7 @@ mod with_key { use mio_extras::timer::Timer; use super::{DataReaderPlCdr, DataWriterPlCdr}; - use crate::{ - polling::TimerPolicy, serialization::pl_cdr_adapters::*, Key, Keyed, Topic, TopicKind, - }; + use crate::{polling::TimerPolicy, serialization::pl_cdr_adapters::*, Key, Keyed, Topic, TopicKind}; pub const TOPIC_KIND: TopicKind = TopicKind::WithKey; diff --git a/src/lib.rs b/src/lib.rs index dedd58c8..f3ab955c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -220,9 +220,7 @@ pub use dds::{ /// CDR. pub use serialization::RepresentationIdentifier; #[doc(inline)] -pub use serialization::{ - CDRDeserializerAdapter, CDRSerializerAdapter, CdrDeserializer, CdrSerializer, -}; +pub use serialization::{CDRDeserializerAdapter, CDRSerializerAdapter, CdrDeserializer, CdrSerializer}; /// Part of RTPS DATA submessage: 4-byte header + serialized data pub use messages::submessages::elements::serialized_payload::SerializedPayload; pub use structure::{ diff --git a/src/serialization.rs b/src/serialization.rs index 2785e512..c8cd749c 100644 --- a/src/serialization.rs +++ b/src/serialization.rs @@ -6,9 +6,7 @@ pub(crate) mod speedy_pl_cdr_helpers; mod representation_identifier; // Most of the CDR encoding/decoding comes from this external crate -pub use cdr_encoding::{ - from_bytes, to_vec, to_writer, CdrDeserializer, CdrSerializer, Error, Result, -}; +pub use cdr_encoding::{from_bytes, to_vec, to_writer, CdrDeserializer, CdrSerializer, Error, Result}; // Export some parts of inner modules pub use cdr_adapters::{ deserialize_from_cdr_with_decoder_and_rep_id, deserialize_from_cdr_with_rep_id, diff --git a/src/serialization/cdr_adapters.rs b/src/serialization/cdr_adapters.rs index cd9221b3..2c329ebc 100644 --- a/src/serialization/cdr_adapters.rs +++ b/src/serialization/cdr_adapters.rs @@ -135,11 +135,12 @@ where } } -/// A default decoder is available for all types that implement -/// `serde::Deserialize`. -impl<'de, D> no_key::DefaultDecoder for CDRDeserializerAdapter +/// A default decoder is available for all owned types that implement +/// `serde::Deserialize`. Borrowing types use `from_bytes_with` with an +/// explicit decoder instead. +impl no_key::DefaultDecoder for CDRDeserializerAdapter where - D: serde::Deserialize<'de>, + D: DeserializeOwned, { type Decoder = CdrDeserializeDecoder; const DECODER: Self::Decoder = CdrDeserializeDecoder(PhantomData); @@ -157,25 +158,25 @@ where /// Decode type based on a `serde::Deserialize` implementation. pub struct CdrDeserializeDecoder(PhantomData); -impl<'de, D> no_key::Decode for CdrDeserializeDecoder +impl<'de, D> no_key::Decode<'de, D> for CdrDeserializeDecoder where D: serde::Deserialize<'de>, { type Error = Error; - fn decode_bytes(self, input_bytes: &[u8], encoding: RepresentationIdentifier) -> Result { + fn decode_bytes(self, input_bytes: &'de [u8], encoding: RepresentationIdentifier) -> Result { deserialize_from_cdr_with_decoder_and_rep_id(input_bytes, encoding, PhantomData).map(|r| r.0) } } -impl with_key::Decode for CdrDeserializeDecoder +impl<'de, Dec, DecKey> with_key::Decode<'de, Dec, DecKey> for CdrDeserializeDecoder where - Dec: DeserializeOwned, - DecKey: DeserializeOwned, + Dec: serde::Deserialize<'de>, + DecKey: serde::Deserialize<'de>, { fn decode_key_bytes( self, - input_key_bytes: &[u8], + input_key_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result { deserialize_from_cdr_with_decoder_and_rep_id(input_key_bytes, encoding, PhantomData) @@ -210,26 +211,27 @@ where } /// Decode type based on a [`serde::de::DeserializeSeed`]-based decoder. -impl<'de, D, S, SK> no_key::Decode for CdrDeserializeSeedDecoder +impl<'de, D, S, SK> no_key::Decode<'de, D> for CdrDeserializeSeedDecoder where S: serde::de::DeserializeSeed<'de, Value = D>, { type Error = Error; - fn decode_bytes(self, input_bytes: &[u8], encoding: RepresentationIdentifier) -> Result { + fn decode_bytes(self, input_bytes: &'de [u8], encoding: RepresentationIdentifier) -> Result { deserialize_from_cdr_with_decoder_and_rep_id(input_bytes, encoding, self.value_seed) .map(|r| r.0) } } -impl<'de, Dec, DecKey, S, SK> with_key::Decode for CdrDeserializeSeedDecoder +impl<'de, Dec, DecKey, S, SK> with_key::Decode<'de, Dec, DecKey> + for CdrDeserializeSeedDecoder where S: serde::de::DeserializeSeed<'de, Value = Dec>, SK: serde::de::DeserializeSeed<'de, Value = DecKey>, { fn decode_key_bytes( self, - input_key_bytes: &[u8], + input_key_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result { deserialize_from_cdr_with_decoder_and_rep_id(input_key_bytes, encoding, self.key_seed) @@ -241,7 +243,7 @@ where /// /// Returns deserialized object. Byte count is discarded. pub fn deserialize_from_cdr_with_rep_id<'de, T>( - input_bytes: &[u8], + input_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result<(T, usize)> where @@ -254,7 +256,7 @@ where /// /// Returns deserialized object and byte count of stream consumed. pub fn deserialize_from_cdr_with_decoder_and_rep_id<'de, S>( - input_bytes: &[u8], + input_bytes: &'de [u8], encoding: RepresentationIdentifier, decoder: S, ) -> Result<(S::Value, usize)> diff --git a/src/serialization/pl_cdr_adapters.rs b/src/serialization/pl_cdr_adapters.rs index c3207179..08d7303c 100644 --- a/src/serialization/pl_cdr_adapters.rs +++ b/src/serialization/pl_cdr_adapters.rs @@ -167,7 +167,7 @@ where /// Decode type based on [`PlCdrDeserialize`] implementation. pub struct PlCdrDeserializer(PhantomData); -impl no_key::Decode for PlCdrDeserializer +impl<'de, D> no_key::Decode<'de, D> for PlCdrDeserializer where D: PlCdrDeserialize, { @@ -175,7 +175,7 @@ where fn decode_bytes( self, - input_bytes: &[u8], + input_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result { match encoding { @@ -189,14 +189,14 @@ where } } -impl with_key::Decode for PlCdrDeserializer +impl<'de, Dec, DecKey> with_key::Decode<'de, Dec, DecKey> for PlCdrDeserializer where Dec: PlCdrDeserialize, DecKey: PlCdrDeserialize, { fn decode_key_bytes( self, - input_bytes: &[u8], + input_bytes: &'de [u8], encoding: RepresentationIdentifier, ) -> Result { match encoding { From bac9dd2bc8e8d51d50c8386fc1d2a7203e2de25c Mon Sep 17 00:00:00 2001 From: Gijs de Jong Date: Fri, 1 May 2026 14:31:09 +0200 Subject: [PATCH 2/3] nightly fmt --- examples/async_shapes_demo/main.rs | 2 +- examples/shapes_demo/main.rs | 2 +- examples/shapes_demo_mio_08/main.rs | 2 +- src/dds/no_key/wrappers.rs | 4 +++- src/discovery/discovery.rs | 4 +++- src/lib.rs | 4 +++- src/serialization.rs | 4 +++- 7 files changed, 15 insertions(+), 7 deletions(-) diff --git a/examples/async_shapes_demo/main.rs b/examples/async_shapes_demo/main.rs index 863ba2be..b45e71f4 100644 --- a/examples/async_shapes_demo/main.rs +++ b/examples/async_shapes_demo/main.rs @@ -19,7 +19,7 @@ use rustdds::{ TopicDescription, TopicKind, }; use rustdds::policy::{Deadline, Durability, History, Reliability}; /* import all QoS - * policies directly */ + * policies directly */ use serde::{Deserialize, Serialize}; use clap::{Arg, ArgMatches, Command}; // command line argument processing use rand::prelude::*; diff --git a/examples/shapes_demo/main.rs b/examples/shapes_demo/main.rs index 0cb842d4..83b36c1d 100644 --- a/examples/shapes_demo/main.rs +++ b/examples/shapes_demo/main.rs @@ -21,7 +21,7 @@ use rustdds::{ StatusEvented, TopicDescription, TopicKind, }; use rustdds::policy::{Deadline, Durability, History, Reliability}; /* import all QoS - * policies directly */ + * policies directly */ use serde::{Deserialize, Serialize}; use clap::{Arg, ArgMatches, Command}; // command line argument processing use mio_06::{Events, Poll, PollOpt, Ready, Token}; // polling diff --git a/examples/shapes_demo_mio_08/main.rs b/examples/shapes_demo_mio_08/main.rs index e30b58e4..cbf1948b 100644 --- a/examples/shapes_demo_mio_08/main.rs +++ b/examples/shapes_demo_mio_08/main.rs @@ -26,7 +26,7 @@ use rustdds::{ TopicDescription, TopicKind, }; use rustdds::policy::{Deadline, Durability, History, Reliability}; /* import all QoS - * policies directly */ + * policies directly */ use serde::{Deserialize, Serialize}; use clap::{Arg, ArgMatches, Command}; // command line argument processing use mio_08::{Events, Interest, Poll, Token}; // non-blocking i/o polling diff --git a/src/dds/no_key/wrappers.rs b/src/dds/no_key/wrappers.rs index 7e426744..dda4d792 100644 --- a/src/dds/no_key/wrappers.rs +++ b/src/dds/no_key/wrappers.rs @@ -2,7 +2,9 @@ use std::{marker::PhantomData, ops::Deref}; use bytes::Bytes; -use crate::{dds::adapters::*, messages::submessages::submessages::RepresentationIdentifier, Keyed}; +use crate::{ + dds::adapters::*, messages::submessages::submessages::RepresentationIdentifier, Keyed, +}; // This wrapper is used to convert NO_KEY types to WITH_KEY // * inside the wrapper there is a NO_KEY type diff --git a/src/discovery/discovery.rs b/src/discovery/discovery.rs index b88c2cc6..b833c493 100644 --- a/src/discovery/discovery.rs +++ b/src/discovery/discovery.rs @@ -135,7 +135,9 @@ mod with_key { use mio_extras::timer::Timer; use super::{DataReaderPlCdr, DataWriterPlCdr}; - use crate::{polling::TimerPolicy, serialization::pl_cdr_adapters::*, Key, Keyed, Topic, TopicKind}; + use crate::{ + polling::TimerPolicy, serialization::pl_cdr_adapters::*, Key, Keyed, Topic, TopicKind, + }; pub const TOPIC_KIND: TopicKind = TopicKind::WithKey; diff --git a/src/lib.rs b/src/lib.rs index f3ab955c..dedd58c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -220,7 +220,9 @@ pub use dds::{ /// CDR. pub use serialization::RepresentationIdentifier; #[doc(inline)] -pub use serialization::{CDRDeserializerAdapter, CDRSerializerAdapter, CdrDeserializer, CdrSerializer}; +pub use serialization::{ + CDRDeserializerAdapter, CDRSerializerAdapter, CdrDeserializer, CdrSerializer, +}; /// Part of RTPS DATA submessage: 4-byte header + serialized data pub use messages::submessages::elements::serialized_payload::SerializedPayload; pub use structure::{ diff --git a/src/serialization.rs b/src/serialization.rs index c8cd749c..2785e512 100644 --- a/src/serialization.rs +++ b/src/serialization.rs @@ -6,7 +6,9 @@ pub(crate) mod speedy_pl_cdr_helpers; mod representation_identifier; // Most of the CDR encoding/decoding comes from this external crate -pub use cdr_encoding::{from_bytes, to_vec, to_writer, CdrDeserializer, CdrSerializer, Error, Result}; +pub use cdr_encoding::{ + from_bytes, to_vec, to_writer, CdrDeserializer, CdrSerializer, Error, Result, +}; // Export some parts of inner modules pub use cdr_adapters::{ deserialize_from_cdr_with_decoder_and_rep_id, deserialize_from_cdr_with_rep_id, From 169889ead4f5ad38de596a3b6b67def4cc4af49c Mon Sep 17 00:00:00 2001 From: Gijs de Jong Date: Fri, 1 May 2026 14:48:40 +0200 Subject: [PATCH 3/3] use upstream cdr-encoding version as dependency + clippy --- Cargo.toml | 5 +++-- src/dds/adapters.rs | 9 +++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8b17aa75..4e3bde9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,7 +62,8 @@ bytes = "1.11" static_assertions = "1.1" thiserror = "2.0.9" # cdr-encoding = { path = "../cdr-encoding"} -cdr-encoding = { version="0.10" } +# cdr-encoding = { version="0.10" } +cdr-encoding = { git = "https://github.com/iblnkn/cdr-encoding/", branch="zero-copy-byte-deserialization" } cdr-encoding-size = { version="^0.5" } futures = "0.3" io-extras = "0.18.0" @@ -118,4 +119,4 @@ termion = "4.0.2" [target.'cfg(target_os = "linux")'.dev-dependencies] -procfs = "0.17" # for ddsperf \ No newline at end of file +procfs = "0.17" # for ddsperf diff --git a/src/dds/adapters.rs b/src/dds/adapters.rs index a8f847b1..5d044a9f 100644 --- a/src/dds/adapters.rs +++ b/src/dds/adapters.rs @@ -148,10 +148,7 @@ pub mod no_key { /// /// Only usable if the adapter has a default decoder, i.e. implements /// `DefaultDecoder`. - fn from_bytes<'de>( - input_bytes: &'de [u8], - encoding: RepresentationIdentifier, - ) -> Result + fn from_bytes(input_bytes: &[u8], encoding: RepresentationIdentifier) -> Result where Self: DefaultDecoder, { @@ -270,8 +267,8 @@ pub mod with_key { /// implementation may fail with Err or `panic!()`. /// /// Only usable if the adapter has a default decoder. - fn key_from_bytes<'de>( - input_bytes: &'de [u8], + fn key_from_bytes( + input_bytes: &[u8], encoding: RepresentationIdentifier, ) -> Result where