diff --git a/Cargo.lock b/Cargo.lock index 015a06ee67..51bc2cd6dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -787,7 +787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", - "half 2.4.1", + "half", ] [[package]] @@ -1601,12 +1601,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "half" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" - [[package]] name = "half" version = "2.4.1" @@ -1957,12 +1951,6 @@ dependencies = [ "nom", ] -[[package]] -name = "iter-read" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c397ca3ea05ad509c4ec451fea28b4771236a376ca1c69fd5143aae0cf8f93c4" - [[package]] name = "itertools" version = "0.10.5" @@ -3652,29 +3640,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-pickle" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762ad136a26407c6a80825813600ceeab5e613660d93d79a41f0ec877171e71" -dependencies = [ - "byteorder", - "iter-read", - "num-bigint", - "num-traits", - "serde", -] - -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half 1.8.3", - "serde", -] - [[package]] name = "serde_derive" version = "1.0.210" @@ -5424,8 +5389,6 @@ dependencies = [ "rand 0.8.5", "rustc_version 0.4.1", "serde", - "serde-pickle", - "serde_cbor", "serde_json", "serde_yaml", "socket2 0.5.7", diff --git a/Cargo.toml b/Cargo.toml index 2fcaaa9cd5..023eb39279 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -154,9 +154,7 @@ secrecy = { version = "0.8.0", features = ["serde", "alloc"] } serde = { version = "1.0.210", default-features = false, features = [ "derive", ] } # Default features are disabled due to usage in no_std crates -serde_cbor = "0.11.2" serde_json = "1.0.128" -serde-pickle = "1.1.1" serde_yaml = "0.9.34" static_init = "1.0.3" stabby = "36.1.1" diff --git a/ci/valgrind-check/src/pub_sub/bin/z_pub_sub.rs b/ci/valgrind-check/src/pub_sub/bin/z_pub_sub.rs index ad96d0b2b0..542cf09736 100644 --- a/ci/valgrind-check/src/pub_sub/bin/z_pub_sub.rs +++ b/ci/valgrind-check/src/pub_sub/bin/z_pub_sub.rs @@ -38,7 +38,7 @@ async fn main() { sample.key_expr().as_str(), sample .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ); }) diff --git a/ci/valgrind-check/src/queryable_get/bin/z_queryable_get.rs b/ci/valgrind-check/src/queryable_get/bin/z_queryable_get.rs index e82ecba477..3340708c8c 100644 --- a/ci/valgrind-check/src/queryable_get/bin/z_queryable_get.rs +++ b/ci/valgrind-check/src/queryable_get/bin/z_queryable_get.rs @@ -64,13 +64,13 @@ async fn main() { sample.key_expr().as_str(), sample .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ), Err(err) => println!( ">> Received (ERROR: '{}')", err.payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ), } diff --git a/commons/zenoh-buffers/src/zbuf.rs b/commons/zenoh-buffers/src/zbuf.rs index 2d5bcca213..74f0f15a81 100644 --- a/commons/zenoh-buffers/src/zbuf.rs +++ b/commons/zenoh-buffers/src/zbuf.rs @@ -494,6 +494,11 @@ impl<'a> ZBufWriter<'a> { self.zslice_writer = zbuf.slices.last_mut().unwrap().writer(); self.zslice_writer.as_mut().unwrap() } + + #[inline] + pub fn reserve(&mut self, additional: usize) { + self.zslice_writer().reserve(additional) + } } impl<'a> HasWriter for &'a mut ZBuf { diff --git a/commons/zenoh-buffers/src/zslice.rs b/commons/zenoh-buffers/src/zslice.rs index 6cefb1ae6e..8733f1abd9 100644 --- a/commons/zenoh-buffers/src/zslice.rs +++ b/commons/zenoh-buffers/src/zslice.rs @@ -143,10 +143,11 @@ impl ZSlice { // See https://github.com/eclipse-zenoh/zenoh/pull/1289#discussion_r1701796640 #[inline] pub(crate) fn writer(&mut self) -> Option { + const MAX_REALLOC_SIZE: usize = 64; let vec = Arc::get_mut(&mut self.buf)? .as_any_mut() .downcast_mut::>()?; - if self.end == vec.len() { + if self.end == vec.len() && (vec.len() < vec.capacity() || vec.len() <= MAX_REALLOC_SIZE) { Some(ZSliceWriter { vec, end: &mut self.end, @@ -294,6 +295,12 @@ pub(crate) struct ZSliceWriter<'a> { end: &'a mut usize, } +impl ZSliceWriter<'_> { + pub(crate) fn reserve(&mut self, additional: usize) { + self.vec.reserve(additional) + } +} + impl Writer for ZSliceWriter<'_> { fn write(&mut self, bytes: &[u8]) -> Result { let len = self.vec.write(bytes)?; diff --git a/commons/zenoh-protocol/src/core/parameters.rs b/commons/zenoh-protocol/src/core/parameters.rs index 38cb368b5b..0652ef6900 100644 --- a/commons/zenoh-protocol/src/core/parameters.rs +++ b/commons/zenoh-protocol/src/core/parameters.rs @@ -374,6 +374,11 @@ impl<'s> From> for Parameters<'s> { } } } +impl<'s> From> for Cow<'s, str> { + fn from(value: Parameters<'s>) -> Self { + value.0 + } +} impl<'a> From> for Cow<'_, Parameters<'a>> { fn from(props: Parameters<'a>) -> Self { diff --git a/examples/examples/z_bytes.rs b/examples/examples/z_bytes.rs index 8f6e82e944..9d27632dfe 100644 --- a/examples/examples/z_bytes.rs +++ b/examples/examples/z_bytes.rs @@ -21,7 +21,7 @@ fn main() { // Numeric: u8, u16, u32, u128, usize, i8, i16, i32, i128, isize, f32, f64 let input = 1234_u32; let payload = ZBytes::from(input); - let output: u32 = payload.deserialize().unwrap(); + let output: u32 = payload.try_deserialize().unwrap(); assert_eq!(input, output); // Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc. // let encoding = Encoding::ZENOH_UINT32; @@ -29,7 +29,7 @@ fn main() { // String let input = String::from("test"); let payload = ZBytes::from(&input); - let output: String = payload.deserialize().unwrap(); + let output: String = payload.try_deserialize().unwrap(); assert_eq!(input, output); // Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc. // let encoding = Encoding::ZENOH_STRING; @@ -38,7 +38,7 @@ fn main() { // See [`zenoh::bytes::ZBytes`] documentation for zero-copy behaviour. let input = Cow::from("test"); let payload = ZBytes::from(&input); - let output: Cow = payload.deserialize().unwrap(); + let output: Cow = payload.try_deserialize().unwrap(); assert_eq!(input, output); // Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc. // let encoding = Encoding::ZENOH_STRING; @@ -46,10 +46,10 @@ fn main() { // Vec: The deserialization should be infallible let input: Vec = vec![1, 2, 3, 4]; let payload = ZBytes::from(&input); - let output: Vec = payload.deserialize().unwrap(); + let output: Vec = payload.try_deserialize().unwrap(); assert_eq!(input, output); // Deserialization of Vec is infallible. See https://docs.rs/unwrap-infallible/latest/unwrap_infallible/. - let output: Vec = payload.deserialize().unwrap_infallible(); + let output: Vec = payload.try_deserialize().unwrap_infallible(); assert_eq!(input, output); // Since the deserialization of `Vec` is infallible, then `ZBytes` can be infallibly converted into a `Vec`. let output: Vec = payload.into(); @@ -61,10 +61,10 @@ fn main() { // See [`zenoh::bytes::ZBytes`] documentation for zero-copy behaviour. let input = Cow::from(vec![1, 2, 3, 4]); let payload = ZBytes::from(&input); - let output: Cow<[u8]> = payload.deserialize().unwrap(); + let output: Cow<[u8]> = payload.try_deserialize().unwrap(); assert_eq!(input, output); // Deserialization of `Cow<[u8]>` is infallible. See https://docs.rs/unwrap-infallible/latest/unwrap_infallible/. - let output: Cow<[u8]> = payload.deserialize().unwrap_infallible(); + let output: Cow<[u8]> = payload.try_deserialize().unwrap_infallible(); assert_eq!(input, output); // Since the deserialization of `Cow<[u8]>` is infallible, then `ZBytes` can be infallibly converted into a `Cow<[u8]>`. let output: Vec = payload.into(); @@ -74,7 +74,7 @@ fn main() { // Writer & Reader // serialization - let mut bytes = ZBytes::empty(); + let mut bytes = ZBytes::new(); let mut writer = bytes.writer(); let i1 = 1234_u32; let i2 = String::from("test"); @@ -94,7 +94,7 @@ fn main() { // Tuple let input = (1234_u32, String::from("test")); let payload = ZBytes::serialize(input.clone()); - let output: (u32, String) = payload.deserialize().unwrap(); + let output: (u32, String) = payload.try_deserialize().unwrap(); assert_eq!(input, output); // Iterator @@ -116,7 +116,7 @@ fn main() { input.insert(0, String::from("abc")); input.insert(1, String::from("def")); let payload = ZBytes::from(input.clone()); - let output = payload.deserialize::>().unwrap(); + let output = payload.try_deserialize::>().unwrap(); assert_eq!(input, output); // JSON @@ -131,7 +131,7 @@ fn main() { }"#; let input: serde_json::Value = serde_json::from_str(data).unwrap(); let payload = ZBytes::try_serialize(input.clone()).unwrap(); - let output: serde_json::Value = payload.deserialize().unwrap(); + let output: serde_json::Value = payload.try_deserialize().unwrap(); assert_eq!(input, output); // Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc. // let encoding = Encoding::APPLICATION_JSON; @@ -146,7 +146,7 @@ fn main() { "#; let input: serde_yaml::Value = serde_yaml::from_str(data).unwrap(); let payload = ZBytes::try_serialize(input.clone()).unwrap(); - let output: serde_yaml::Value = payload.deserialize().unwrap(); + let output: serde_yaml::Value = payload.try_deserialize().unwrap(); assert_eq!(input, output); // Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc. // let encoding = Encoding::APPLICATION_YAML; @@ -166,7 +166,7 @@ fn main() { }; let payload = ZBytes::from(input.encode_to_vec()); let output = - EntityInfo::decode(Cursor::new(payload.deserialize::>().unwrap())).unwrap(); + EntityInfo::decode(Cursor::new(payload.try_deserialize::>().unwrap())).unwrap(); assert_eq!(input, output); // Corresponding encoding to be used in operations like `.put()`, `.reply()`, etc. // let encoding = Encoding::APPLICATION_PROTOBUF; diff --git a/examples/examples/z_bytes_shm.rs b/examples/examples/z_bytes_shm.rs index 1db1680be7..7a55f01065 100644 --- a/examples/examples/z_bytes_shm.rs +++ b/examples/examples/z_bytes_shm.rs @@ -62,7 +62,7 @@ fn main() { // branch to illustrate immutable access to SHM data { // deserialize ZBytes as an immutably borrowed zshm (ZBytes -> &zshm) - let borrowed_shm_buf: &zshm = payload.deserialize().unwrap(); + let borrowed_shm_buf: &zshm = payload.try_deserialize().unwrap(); // immutable API let _data: &[u8] = borrowed_shm_buf; diff --git a/examples/examples/z_get.rs b/examples/examples/z_get.rs index 7966d5938a..172c331d02 100644 --- a/examples/examples/z_get.rs +++ b/examples/examples/z_get.rs @@ -49,7 +49,7 @@ async fn main() { // Refer to z_bytes.rs to see how to deserialize different types of message let payload = sample .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); println!( ">> Received ('{}': '{}')", @@ -60,7 +60,7 @@ async fn main() { Err(err) => { let payload = err .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); println!(">> Received (ERROR: '{}')", payload); } diff --git a/examples/examples/z_get_liveliness.rs b/examples/examples/z_get_liveliness.rs index b0c4006e13..5048093218 100644 --- a/examples/examples/z_get_liveliness.rs +++ b/examples/examples/z_get_liveliness.rs @@ -40,7 +40,7 @@ async fn main() { Err(err) => { let payload = err .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); println!(">> Received (ERROR: '{}')", payload); } diff --git a/examples/examples/z_get_shm.rs b/examples/examples/z_get_shm.rs index 5c4a4f17fe..e9ed30c1d6 100644 --- a/examples/examples/z_get_shm.rs +++ b/examples/examples/z_get_shm.rs @@ -78,7 +78,7 @@ async fn main() { match reply.result() { Ok(sample) => { print!(">> Received ('{}': ", sample.key_expr().as_str()); - match sample.payload().deserialize::<&zshm>() { + match sample.payload().try_deserialize::<&zshm>() { Ok(payload) => println!("'{}')", String::from_utf8_lossy(payload),), Err(e) => println!("'Not a ShmBufInner: {:?}')", e), } @@ -86,7 +86,7 @@ async fn main() { Err(err) => { let payload = err .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); println!(">> Received (ERROR: '{}')", payload); } diff --git a/examples/examples/z_pull.rs b/examples/examples/z_pull.rs index c677b545b8..daf364345c 100644 --- a/examples/examples/z_pull.rs +++ b/examples/examples/z_pull.rs @@ -43,7 +43,7 @@ async fn main() { Ok(sample) => { let payload = sample .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); println!( ">> [Subscriber] Pulled {} ('{}': '{}')... performing a computation of {:#?}", diff --git a/examples/examples/z_queryable.rs b/examples/examples/z_queryable.rs index b3b5ca9bf0..3cf90618dc 100644 --- a/examples/examples/z_queryable.rs +++ b/examples/examples/z_queryable.rs @@ -43,7 +43,7 @@ async fn main() { Some(query_payload) => { // Refer to z_bytes.rs to see how to deserialize different types of message let deserialized_payload = query_payload - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); println!( ">> [Queryable ] Received Query '{}' with payload '{}'", diff --git a/examples/examples/z_queryable_shm.rs b/examples/examples/z_queryable_shm.rs index db00ddb118..37846b28e9 100644 --- a/examples/examples/z_queryable_shm.rs +++ b/examples/examples/z_queryable_shm.rs @@ -144,7 +144,7 @@ fn handle_bytes(bytes: &ZBytes) -> (&str, String) { // if Zenoh is built with SHM support and with SHM API we can detect the exact buffer type #[cfg(all(feature = "shared-memory", feature = "unstable"))] - match bytes.deserialize::<&zshm>() { + match bytes.try_deserialize::<&zshm>() { Ok(_) => "SHM", Err(_) => "RAW", } @@ -157,7 +157,7 @@ fn handle_bytes(bytes: &ZBytes) -> (&str, String) { // // Refer to z_bytes.rs to see how to deserialize different types of message let bytes_string = bytes - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); (bytes_type, bytes_string) diff --git a/examples/examples/z_storage.rs b/examples/examples/z_storage.rs index 9f6f50b16f..1ed900781b 100644 --- a/examples/examples/z_storage.rs +++ b/examples/examples/z_storage.rs @@ -51,7 +51,7 @@ async fn main() { select!( sample = subscriber.recv_async() => { let sample = sample.unwrap(); - let payload = sample.payload().deserialize::().unwrap_or_else(|e| format!("{}", e)); + let payload = sample.payload().try_deserialize::().unwrap_or_else(|e| format!("{}", e)); println!(">> [Subscriber] Received {} ('{}': '{}')", sample.kind(), sample.key_expr().as_str(),payload); match sample.kind() { SampleKind::Delete => stored.remove(&sample.key_expr().to_string()), diff --git a/examples/examples/z_sub.rs b/examples/examples/z_sub.rs index 26fc768737..f13f98ad0b 100644 --- a/examples/examples/z_sub.rs +++ b/examples/examples/z_sub.rs @@ -33,7 +33,7 @@ async fn main() { // Refer to z_bytes.rs to see how to deserialize different types of message let payload = sample .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); print!( @@ -44,7 +44,7 @@ async fn main() { ); if let Some(att) = sample.attachment() { let att = att - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); print!(" ({})", att); } diff --git a/examples/examples/z_sub_shm.rs b/examples/examples/z_sub_shm.rs index a4660485dc..fb6a54472e 100644 --- a/examples/examples/z_sub_shm.rs +++ b/examples/examples/z_sub_shm.rs @@ -104,7 +104,7 @@ fn handle_bytes(bytes: &ZBytes) -> (&str, String) { // if Zenoh is built with SHM support and with SHM API we can detect the exact buffer type #[cfg(all(feature = "shared-memory", feature = "unstable"))] - match bytes.deserialize::<&zshm>() { + match bytes.try_deserialize::<&zshm>() { Ok(_) => "SHM", Err(_) => "RAW", } @@ -117,7 +117,7 @@ fn handle_bytes(bytes: &ZBytes) -> (&str, String) { // // Refer to z_bytes.rs to see how to deserialize different types of message let bytes_string = bytes - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); (bytes_type, bytes_string) diff --git a/plugins/zenoh-plugin-example/src/lib.rs b/plugins/zenoh-plugin-example/src/lib.rs index 9fc53c1c80..d6f0cd3ec2 100644 --- a/plugins/zenoh-plugin-example/src/lib.rs +++ b/plugins/zenoh-plugin-example/src/lib.rs @@ -196,7 +196,7 @@ async fn run(runtime: Runtime, selector: KeyExpr<'_>, flag: Arc) { // on sample received by the Subscriber sample = sub.recv_async() => { let sample = sample.unwrap(); - let payload = sample.payload().deserialize::>().unwrap_or_else(|e| Cow::from(e.to_string())); + let payload = sample.payload().try_deserialize::>().unwrap_or_else(|e| Cow::from(e.to_string())); info!("Received data ('{}': '{}')", sample.key_expr(), payload); stored.insert(sample.key_expr().to_string(), sample); }, diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index c06fc09951..f8606171dc 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -110,22 +110,22 @@ fn payload_to_json(payload: &ZBytes, encoding: &Encoding) -> serde_json::Value { // If it is a JSON try to deserialize as json, if it fails fallback to base64 &Encoding::APPLICATION_JSON | &Encoding::TEXT_JSON | &Encoding::TEXT_JSON5 => { payload - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| { tracing::warn!("Encoding is JSON but data is not JSON, converting to base64, Error: {e:?}"); - serde_json::Value::String(base64_encode(&Cow::from(payload))) + serde_json::Value::String(base64_encode(&payload.deserialize::>())) }) } &Encoding::TEXT_PLAIN | &Encoding::ZENOH_STRING => serde_json::Value::String( payload - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| { tracing::warn!("Encoding is String but data is not String, converting to base64, Error: {e:?}"); - base64_encode(&Cow::from(payload)) + base64_encode(&payload.deserialize::>()) }), ), // otherwise convert to JSON string - _ => serde_json::Value::String(base64_encode(&Cow::from(payload))), + _ => serde_json::Value::String(base64_encode(&payload.deserialize::>())), } } } @@ -172,7 +172,7 @@ fn sample_to_html(sample: &Sample) -> String { sample.key_expr().as_str(), sample .payload() - .deserialize::>() + .try_deserialize::>() .unwrap_or_default() ) } @@ -183,7 +183,9 @@ fn result_to_html(sample: Result<&Sample, &ReplyError>) -> String { Err(err) => { format!( "
ERROR
\n
{}
\n", - err.payload().deserialize::>().unwrap_or_default() + err.payload() + .try_deserialize::>() + .unwrap_or_default() ) } } @@ -211,7 +213,7 @@ async fn to_raw_response(results: flume::Receiver) -> Response { Cow::from(sample.encoding()).as_ref(), &sample .payload() - .deserialize::>() + .try_deserialize::>() .unwrap_or_default(), ), Err(value) => response( @@ -219,7 +221,7 @@ async fn to_raw_response(results: flume::Receiver) -> Response { Cow::from(value.encoding()).as_ref(), &value .payload() - .deserialize::>() + .try_deserialize::>() .unwrap_or_default(), ), }, diff --git a/plugins/zenoh-plugin-storage-manager/src/replication/aligner.rs b/plugins/zenoh-plugin-storage-manager/src/replication/aligner.rs index e805bda26c..51fbdec75c 100644 --- a/plugins/zenoh-plugin-storage-manager/src/replication/aligner.rs +++ b/plugins/zenoh-plugin-storage-manager/src/replication/aligner.rs @@ -89,7 +89,7 @@ impl Replication { }; let alignment_query = - match bincode::deserialize::(&attachment.into::>()) { + match bincode::deserialize::(&attachment.deserialize::>()) { Ok(alignment) => alignment, Err(e) => { tracing::error!( @@ -368,7 +368,7 @@ impl Replication { continue; } Some(attachment) => match bincode::deserialize::( - &attachment.into::>(), + &attachment.deserialize::>(), ) { Err(e) => { tracing::error!( @@ -655,7 +655,7 @@ async fn reply_to_query(query: &Query, reply: AlignmentReply, value: Option( - &sample.payload().into::>(), + &sample.payload().deserialize::>(), ) { Ok(other_digest) => other_digest, Err(e) => { diff --git a/plugins/zenoh-plugin-storage-manager/src/storages_mgt/service.rs b/plugins/zenoh-plugin-storage-manager/src/storages_mgt/service.rs index 42e82eae94..297e85b829 100644 --- a/plugins/zenoh-plugin-storage-manager/src/storages_mgt/service.rs +++ b/plugins/zenoh-plugin-storage-manager/src/storages_mgt/service.rs @@ -634,7 +634,7 @@ fn serialize_update(update: &Update) -> String { kind, data: StoredData { value, timestamp }, } = update; - let zbuf: ZBuf = value.payload().into(); + let zbuf: ZBuf = value.payload().deserialize(); let result = ( kind.to_string(), diff --git a/plugins/zenoh-plugin-storage-manager/tests/operations.rs b/plugins/zenoh-plugin-storage-manager/tests/operations.rs index c3ddf67d2e..263213e53a 100644 --- a/plugins/zenoh-plugin-storage-manager/tests/operations.rs +++ b/plugins/zenoh-plugin-storage-manager/tests/operations.rs @@ -107,7 +107,10 @@ async fn test_updates_in_order() { // expects exactly one sample let data = get_data(&session, "operation/test/a").await; assert_eq!(data.len(), 1); - assert_eq!(data[0].payload().deserialize::>().unwrap(), "1"); + assert_eq!( + data[0].payload().try_deserialize::>().unwrap(), + "1" + ); put_data( &session, @@ -122,7 +125,10 @@ async fn test_updates_in_order() { // expects exactly one sample let data = get_data(&session, "operation/test/b").await; assert_eq!(data.len(), 1); - assert_eq!(data[0].payload().deserialize::>().unwrap(), "2"); + assert_eq!( + data[0].payload().try_deserialize::>().unwrap(), + "2" + ); delete_data( &session, @@ -140,7 +146,10 @@ async fn test_updates_in_order() { // expects exactly one sample let data = get_data(&session, "operation/test/b").await; assert_eq!(data.len(), 1); - assert_eq!(data[0].payload().deserialize::>().unwrap(), "2"); + assert_eq!( + data[0].payload().try_deserialize::>().unwrap(), + "2" + ); assert_eq!(data[0].key_expr().as_str(), "operation/test/b"); drop(storage); diff --git a/plugins/zenoh-plugin-storage-manager/tests/wildcard.rs b/plugins/zenoh-plugin-storage-manager/tests/wildcard.rs index b4c7ddd8f2..21f823f8a0 100644 --- a/plugins/zenoh-plugin-storage-manager/tests/wildcard.rs +++ b/plugins/zenoh-plugin-storage-manager/tests/wildcard.rs @@ -120,7 +120,10 @@ async fn test_wild_card_in_order() { let data = get_data(&session, "wild/test/*").await; assert_eq!(data.len(), 1); assert_eq!(data[0].key_expr().as_str(), "wild/test/a"); - assert_eq!(data[0].payload().deserialize::>().unwrap(), "2"); + assert_eq!( + data[0].payload().try_deserialize::>().unwrap(), + "2" + ); put_data( &session, @@ -140,14 +143,14 @@ async fn test_wild_card_in_order() { assert!(["2", "3"].contains( &data[0] .payload() - .deserialize::>() + .try_deserialize::>() .unwrap() .as_ref() )); assert!(["2", "3"].contains( &data[1] .payload() - .deserialize::>() + .try_deserialize::>() .unwrap() .as_ref() )); @@ -167,8 +170,14 @@ async fn test_wild_card_in_order() { assert_eq!(data.len(), 2); assert!(["wild/test/a", "wild/test/b"].contains(&data[0].key_expr().as_str())); assert!(["wild/test/a", "wild/test/b"].contains(&data[1].key_expr().as_str())); - assert_eq!(data[0].payload().deserialize::>().unwrap(), "4"); - assert_eq!(data[1].payload().deserialize::>().unwrap(), "4"); + assert_eq!( + data[0].payload().try_deserialize::>().unwrap(), + "4" + ); + assert_eq!( + data[1].payload().try_deserialize::>().unwrap(), + "4" + ); delete_data( &session, diff --git a/zenoh-ext/examples/examples/z_query_sub.rs b/zenoh-ext/examples/examples/z_query_sub.rs index 0d01cb20c7..18f9f74da5 100644 --- a/zenoh-ext/examples/examples/z_query_sub.rs +++ b/zenoh-ext/examples/examples/z_query_sub.rs @@ -51,7 +51,7 @@ async fn main() { while let Ok(sample) = subscriber.recv_async().await { let payload = sample .payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)); println!( ">> [Subscriber] Received {} ('{}': '{}')", diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index d7c5f447b9..3c12225a31 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -32,25 +32,25 @@ maintenance = { status = "actively-developed" } auth_pubkey = ["zenoh-transport/auth_pubkey"] auth_usrpwd = ["zenoh-transport/auth_usrpwd"] default = [ - "auth_pubkey", - "auth_usrpwd", - "transport_multilink", - "transport_compression", - "transport_quic", - "transport_tcp", - "transport_tls", - "transport_udp", - "transport_unixsock-stream", - "transport_ws", + "auth_pubkey", + "auth_usrpwd", + "transport_multilink", + "transport_compression", + "transport_quic", + "transport_tcp", + "transport_tls", + "transport_udp", + "transport_unixsock-stream", + "transport_ws", ] internal = ["zenoh-keyexpr/internal", "zenoh-config/internal"] plugins = [] runtime_plugins = ["plugins"] shared-memory = [ - "zenoh-shm", - "zenoh-protocol/shared-memory", - "zenoh-transport/shared-memory", - "zenoh-buffers/shared-memory", + "zenoh-shm", + "zenoh-protocol/shared-memory", + "zenoh-transport/shared-memory", + "zenoh-buffers/shared-memory", ] stats = ["zenoh-transport/stats", "zenoh-protocol/stats"] transport_multilink = ["zenoh-transport/transport_multilink"] @@ -85,9 +85,7 @@ petgraph = { workspace = true } phf = { workspace = true } rand = { workspace = true, features = ["default"] } serde = { workspace = true, features = ["default"] } -serde_cbor = { workspace = true } serde_json = { workspace = true } -serde-pickle = { workspace = true } serde_yaml = { workspace = true } socket2 = { workspace = true } uhlc = { workspace = true, features = ["default"] } diff --git a/zenoh/src/api/admin.rs b/zenoh/src/api/admin.rs index b96fc75dd2..a39ad113ec 100644 --- a/zenoh/src/api/admin.rs +++ b/zenoh/src/api/admin.rs @@ -69,9 +69,9 @@ pub(crate) fn on_admin_query(session: &WeakSession, query: Query) { let key_expr = *KE_PREFIX / own_zid / *KE_SESSION / *KE_TRANSPORT_UNICAST / zid; if query.key_expr().intersects(&key_expr) { if let Ok(value) = serde_json::value::to_value(peer.clone()) { - match ZBytes::try_from(value) { - Ok(zbuf) => { - let _ = query.reply(key_expr, zbuf).wait(); + match ZBytes::try_serialize(value) { + Ok(zbytes) => { + let _ = query.reply(key_expr, zbytes).wait(); } Err(e) => tracing::debug!("Admin query error: {}", e), } @@ -91,9 +91,9 @@ pub(crate) fn on_admin_query(session: &WeakSession, query: Query) { / lid; if query.key_expr().intersects(&key_expr) { if let Ok(value) = serde_json::value::to_value(link) { - match ZBytes::try_from(value) { - Ok(zbuf) => { - let _ = query.reply(key_expr, zbuf).wait(); + match ZBytes::try_serialize(value) { + Ok(zbytes) => { + let _ = query.reply(key_expr, zbytes).wait(); } Err(e) => tracing::debug!("Admin query error: {}", e), } diff --git a/zenoh/src/api/builders/publisher.rs b/zenoh/src/api/builders/publisher.rs index 9db37fa36a..a8ccc5022f 100644 --- a/zenoh/src/api/builders/publisher.rs +++ b/zenoh/src/api/builders/publisher.rs @@ -228,7 +228,7 @@ impl Wait for PublicationBuilder, PublicationBuilderDel fn wait(self) -> ::To { self.publisher.session.0.resolve_put( &self.publisher.key_expr?, - ZBytes::empty(), + ZBytes::new(), SampleKind::Delete, Encoding::ZENOH_BYTES, self.publisher.congestion_control, @@ -459,7 +459,7 @@ impl Wait for PublicationBuilder<&Publisher<'_>, PublicationBuilderDelete> { fn wait(self) -> ::To { self.publisher.session.resolve_put( &self.publisher.key_expr, - ZBytes::empty(), + ZBytes::new(), SampleKind::Delete, Encoding::ZENOH_BYTES, self.publisher.congestion_control, diff --git a/zenoh/src/api/builders/sample.rs b/zenoh/src/api/builders/sample.rs index cb7ada9e4f..0c41e6b829 100644 --- a/zenoh/src/api/builders/sample.rs +++ b/zenoh/src/api/builders/sample.rs @@ -1,3 +1,4 @@ +use std::convert::Infallible; // // Copyright (c) 2024 ZettaScale Technology // @@ -19,15 +20,18 @@ use zenoh_protocol::core::CongestionControl; #[cfg(feature = "unstable")] use zenoh_protocol::core::Reliability; -use crate::api::{ - bytes::{OptionZBytes, ZBytes}, - encoding::Encoding, - key_expr::KeyExpr, - publisher::Priority, - sample::{QoS, QoSBuilder, Sample, SampleKind}, -}; #[cfg(feature = "unstable")] use crate::sample::SourceInfo; +use crate::{ + api::{ + bytes::{OptionZBytes, ZBytes}, + encoding::Encoding, + key_expr::KeyExpr, + publisher::Priority, + sample::{QoS, QoSBuilder, Sample, SampleKind}, + }, + bytes::Serialize, +}; pub trait QoSBuilderTrait { /// Change the `congestion_control` to apply when routing the data. @@ -72,18 +76,18 @@ pub struct SampleBuilder { } impl SampleBuilder { - pub fn put( + pub fn put<'p, IntoKeyExpr, IntoZBytes>( key_expr: IntoKeyExpr, payload: IntoZBytes, ) -> SampleBuilder where IntoKeyExpr: Into>, - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { Self { sample: Sample { key_expr: key_expr.into(), - payload: payload.into(), + payload: ZBytes::serialize(payload), kind: SampleKind::Put, encoding: Encoding::default(), timestamp: None, @@ -98,11 +102,11 @@ impl SampleBuilder { } } - pub fn payload(mut self, payload: IntoZBytes) -> Self + pub fn payload<'p, IntoZBytes>(mut self, payload: IntoZBytes) -> Self where - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { - self.sample.payload = payload.into(); + self.sample.payload = ZBytes::serialize(payload); self } } @@ -115,7 +119,7 @@ impl SampleBuilder { Self { sample: Sample { key_expr: key_expr.into(), - payload: ZBytes::empty(), + payload: ZBytes::new(), kind: SampleKind::Delete, encoding: Encoding::default(), timestamp: None, diff --git a/zenoh/src/api/bytes.rs b/zenoh/src/api/bytes.rs index cd7196c233..e540802cf4 100644 --- a/zenoh/src/api/bytes.rs +++ b/zenoh/src/api/bytes.rs @@ -13,16 +13,12 @@ // //! ZBytes primitives. -use std::{ - borrow::Cow, collections::HashMap, convert::Infallible, fmt::Debug, marker::PhantomData, - str::Utf8Error, string::FromUtf8Error, sync::Arc, -}; +use std::{borrow::Cow, convert::Infallible, fmt::Debug, marker::PhantomData, mem::size_of}; use uhlc::Timestamp; -use unwrap_infallible::UnwrapInfallible; use zenoh_buffers::{ buffer::{Buffer, SplitBuffer}, - reader::{HasReader, Reader}, + reader::{DidntRead, HasReader, Reader}, writer::HasWriter, ZBuf, ZBufReader, ZBufWriter, ZSlice, ZSliceBuffer, }; @@ -31,12 +27,9 @@ use zenoh_protocol::{ core::{Encoding as EncodingProto, Parameters}, zenoh::ext::AttachmentType, }; -#[cfg(feature = "shared-memory")] +#[cfg(all(feature = "shared-memory", feature = "unstable"))] use zenoh_shm::{ - api::buffer::{ - zshm::{zshm, ZShm}, - zshmmut::{zshmmut, ZShmMut}, - }, + api::buffer::{zshm::zshm, zshmmut::zshmmut}, ShmBufInner, }; @@ -86,24 +79,40 @@ impl From for Option { } } -/// Trait to encode a type `T` into a [`ZBytes`]. -pub trait Serialize { - type Output; +pub trait SerializedSize { + const FIXED_SIZE: Option = None; +} +impl SerializedSize for &T { + const FIXED_SIZE: Option = T::FIXED_SIZE; +} + +pub enum Serialized<'a> { + Slice(&'a [u8]), + ZBytes(ZBytes), +} + +impl<'a> From<&'a [u8]> for Serialized<'a> { + fn from(value: &'a [u8]) -> Self { + Self::Slice(value) + } +} - /// The implementer should take care of serializing the type `T` into a [`ZBytes`]. - /// If [`Encoding`] metadata is important in a given system, the caller should take care - /// of setting the proprer [`Encoding`] value when calling functions like [`crate::Session::put`]. - fn serialize(self, t: T) -> Self::Output; +impl From for Serialized<'_> { + fn from(value: ZBytes) -> Self { + Self::ZBytes(value) + } } -pub trait Deserialize { - type Input<'a>; +pub trait Serialize<'a>: Sized + SerializedSize { type Error; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error>; + fn serialize(self) -> Result, Self::Error>; +} - /// The implementer should take care of deserializing a [`ZBytes`] into the type `T`. - /// If [`Encoding`] metadata is required in a given system, the caller should take care of checking the proprer - /// [`Encoding`] value (e.g. [`crate::sample::Sample::encoding`]) to select the right type `T` to deserialize into. - fn deserialize(self, t: Self::Input<'_>) -> Result; +pub trait Deserialize<'a>: Sized + SerializedSize { + fn read(reader: &mut ZBytesReader) -> Result; + fn deserialize(zbytes: &'a ZBytes) -> Result; + fn try_from_zbytes(zbytes: ZBytes) -> Result; } /// ZBytes contains the serialized bytes of user data. @@ -111,15 +120,10 @@ pub trait Deserialize { /// `ZBytes` provides convenient methods to the user for serialization/deserialization based on the default Zenoh serializer [`ZSerde`]. /// /// **NOTE 1:** Zenoh semantic and protocol take care of sending and receiving bytes without restricting the actual data types. -/// -/// **NOTE 2:** [`ZSerde`] is the default serializer/deserializer provided for convenience to the users to deal with primitives data types via -/// a simple out-of-the-box encoding. That is, [`ZSerde`] is provided as a facilitator for simple use cases that need to send/receive data -/// over Zenoh, and doing so potentially to/from different programming languages. Make simple use cases simple and provide freedom for more -/// advanced use cases. -/// -/// **NOTE 3:** [`ZSerde`] is **NOT** by any means the only serializer/deserializer users can use nor a limitation to the types supported by Zenoh. -/// [`ZSerde`] does not have the ambition nor the plan to be a full alternative of more complete seriliazation libraries like *serde*, *protobuf*, -/// *bincode*, *flatbuffers*, etc. Users are free and encouraged to use any serializer/deserializer of their choice that better suits their use case. +/// [`ZSerde`] is the default serializer/deserializer provided for convenience to the users to deal with primitives data types via +/// a simple out-of-the-box encoding. [`ZSerde`] is **NOT** by any means the only serializer/deserializer users can use nor a limitation +/// to the types supported by Zenoh. Users are free and encouraged to use any serializer/deserializer of their choice like *serde*, +/// *protobuf*, *bincode*, *flatbuffers*, etc. /// /// `ZBytes` can be used to serialize a single type: /// ```rust @@ -127,7 +131,7 @@ pub trait Deserialize { /// /// let start = String::from("abc"); /// let bytes = ZBytes::serialize(start.clone()); -/// let end: String = bytes.deserialize().unwrap(); +/// let end: String = bytes.try_deserialize().unwrap(); /// assert_eq!(start, end); /// ``` /// @@ -137,12 +141,12 @@ pub trait Deserialize { /// /// let start = (String::from("abc"), String::from("def")); /// let bytes = ZBytes::serialize(start.clone()); -/// let end: (String, String) = bytes.deserialize().unwrap(); +/// let end: (String, String) = bytes.try_deserialize().unwrap(); /// assert_eq!(start, end); /// /// let start = (1_u8, 3.14_f32, String::from("abc")); /// let bytes = ZBytes::serialize(start.clone()); -/// let end: (u8, f32, String) = bytes.deserialize().unwrap(); +/// let end: (u8, f32, String) = bytes.try_deserialize().unwrap(); /// assert_eq!(start, end); /// `````` /// @@ -178,7 +182,7 @@ pub trait Deserialize { /// three: vec![42u8; 42], /// }; /// -/// let mut bytes = ZBytes::empty(); +/// let mut bytes = ZBytes::new(); /// let mut writer = bytes.writer(); /// /// writer.serialize(&start.one); @@ -194,9 +198,9 @@ pub trait Deserialize { /// assert_eq!(start, end); /// ``` /// -/// **NOTE 4:** `ZBytes` may store data in non-contiguous regions of memory. +/// **NOTE 2:** `ZBytes` may store data in non-contiguous regions of memory. /// The typical case for `ZBytes` to store data in different memory regions is when data is received fragmented from the network. -/// The user then can decided to use [`ZBytes::deserialize`], [`ZBytes::reader`], [`ZBytes::into`], or [`ZBytes::slices`] depending +/// The user then can decided to use [`ZBytes::try_deserialize`], [`ZBytes::reader`], [`ZBytes::deserialize`], or [`ZBytes::slices`] depending /// on their needs. /// /// To directly access raw data as contiguous slice it is preferred to convert `ZBytes` into a [`std::borrow::Cow<[u8]>`]. @@ -234,32 +238,21 @@ pub struct ZBytes(ZBuf); impl ZBytes { /// Create an empty ZBytes. - pub const fn empty() -> Self { + pub const fn new() -> Self { Self(ZBuf::empty()) } - /// Create a [`ZBytes`] from any type `T` that implements [`Into`]. - #[doc(hidden)] - pub fn new(t: T) -> Self - where - T: Into, - { - Self(t.into()) - } - - /// Returns whether the [`ZBytes`] is empty or not. + /// Returns whether the ZBytes is empty or not. pub fn is_empty(&self) -> bool { self.0.is_empty() } - /// Returns the total number of bytes in the [`ZBytes`]. + /// Returns the total number of bytes in the ZBytes. pub fn len(&self) -> usize { self.0.len() } /// Get a [`ZBytesReader`] implementing [`std::io::Read`] trait. - /// - /// See [`ZBytesWriter`] on how to chain the deserialization of different types from a single [`ZBytes`]. pub fn reader(&self) -> ZBytesReader<'_> { ZBytesReader(self.0.reader()) } @@ -271,7 +264,7 @@ impl ZBytes { { let mut buf: Vec = vec![]; reader.read_to_end(&mut buf)?; - Ok(ZBytes::new(buf)) + Ok(ZBytes(buf.into())) } /// Get a [`ZBytesWriter`] implementing [`std::io::Write`] trait. @@ -294,13 +287,9 @@ impl ZBytes { /// assert_eq!(list[index], elem.unwrap()); /// } /// ``` - pub fn iter(&self) -> ZBytesIterator<'_, T> - where - for<'b> ZSerde: Deserialize = &'b ZBytes>, - for<'b> >::Error: Debug, - { + pub fn iter(&self) -> ZBytesIterator<'_, T> { ZBytesIterator { - reader: self.0.reader(), + reader: self.reader(), _t: PhantomData::, } } @@ -320,7 +309,7 @@ impl ZBytes { /// /// let buf1: Vec = vec![1, 2, 3]; /// let buf2: Vec = vec![4, 5, 6, 7, 8]; - /// let mut zbs = ZBytes::empty(); + /// let mut zbs = ZBytes::new(); /// let mut writer = zbs.writer(); /// writer.write(&buf1); /// writer.write(&buf2); @@ -336,7 +325,7 @@ impl ZBytes { /// let out: Vec = zbs.slices().fold(Vec::new(), |mut b, x| { b.extend_from_slice(x); b }); /// // The previous line is the equivalent of /// // let out: Vec = zbs.into(); - /// assert_eq!(buf, out); + /// assert_eq!(buf, out); /// ``` /// /// The example below shows how the [`ZBytesWriter::append`] simply appends the slices of one [`ZBytes`] @@ -348,7 +337,7 @@ impl ZBytes { /// let buf1: Vec = vec![1, 2, 3]; /// let buf2: Vec = vec![4, 5, 6, 7, 8]; /// - /// let mut zbs = ZBytes::empty(); + /// let mut zbs = ZBytes::new(); /// let mut writer = zbs.writer(); /// writer.append(ZBytes::from(buf1.clone())); /// writer.append(ZBytes::from(buf2.clone())); @@ -368,14 +357,11 @@ impl ZBytes { /// /// let start = String::from("abc"); /// let bytes = ZBytes::serialize(start.clone()); - /// let end: String = bytes.deserialize().unwrap(); + /// let end: String = bytes.try_deserialize().unwrap(); /// assert_eq!(start, end); /// ``` - pub fn serialize(t: T) -> Self - where - ZSerde: Serialize, - { - ZSerde.serialize(t) + pub fn serialize<'a, T: Serialize<'a, Error = Infallible>>(t: T) -> Self { + Self::try_serialize(t).unwrap() } /// Try serializing an object of type `T` as a [`ZBytes`] using the [`ZSerde`]. @@ -399,36 +385,33 @@ impl ZBytes { /// let start: Value = serde_json::from_str(data).unwrap(); /// // The serialization of a serde_json::Value is faillable (see `serde_json::to_string()`). /// let bytes = ZBytes::try_serialize(start.clone()).unwrap(); - /// let end: Value = bytes.deserialize().unwrap(); + /// let end: Value = bytes.try_deserialize().unwrap(); /// assert_eq!(start, end); /// ``` - pub fn try_serialize(t: T) -> Result - where - ZSerde: Serialize>, - { - ZSerde.serialize(t) + pub fn try_serialize<'a, T: Serialize<'a>>(t: T) -> Result { + if T::FIXED_SIZE.is_some() { + let mut zbytes = ZBytes::new(); + t.write(&mut zbytes.writer())?; + Ok(zbytes) + } else { + Ok(match t.serialize()? { + Serialized::Slice(s) => s.into(), + Serialized::ZBytes(zbytes) => zbytes, + }) + } } /// Deserialize an object of type `T` using [`ZSerde`]. /// /// See [`ZBytes::serialize`] and [`ZBytes::try_serialize`] for the examples. /// - /// See [`ZBytes::into`] for infallible conversion, e.g. to get raw bytes. - pub fn deserialize<'a, T>(&'a self) -> Result>::Error> - where - ZSerde: Deserialize = &'a ZBytes>, - >::Error: Debug, - { - ZSerde.deserialize(self) - } - - /// Deserialize an object of type `T` using [`ZSerde`]. - pub fn deserialize_mut<'a, T>(&'a mut self) -> Result>::Error> - where - ZSerde: Deserialize = &'a mut ZBytes>, - >::Error: Debug, - { - ZSerde.deserialize(self) + /// See [`ZBytes::deserialize`] for infallible conversion, e.g. to get raw bytes. + pub fn try_deserialize<'a, T: Deserialize<'a>>(&'a self) -> Result { + if T::FIXED_SIZE.is_some() { + T::read(&mut self.reader()) + } else { + T::deserialize(self) + } } /// Infallibly deserialize an object of type `T` using [`ZSerde`]. @@ -456,69 +439,59 @@ impl ZBytes { /// /// let buf: Vec = vec![0, 1, 2, 3]; /// let bytes = ZBytes::from(buf.clone()); - /// let deser: Vec = bytes.into(); + /// let deser: Vec = bytes.deserialize(); /// assert_eq!(buf.as_slice(), deser.as_slice()); /// ``` /// /// If you want to be sure that no copy is performed at all, then you should use [`ZBytes::slices`]. /// Please note that in this case data may not be contiguous in memory and it is the responsibility of the user to properly parse the raw slices. - pub fn into<'a, T>(&'a self) -> T - where - ZSerde: Deserialize = &'a ZBytes, Error = Infallible>, - >::Error: Debug, - { - ZSerde.deserialize(self).unwrap_infallible() + pub fn deserialize<'a, T: Deserialize<'a>>(&'a self) -> T { + self.try_deserialize().unwrap() } - /// Infallibly deserialize an object of type `T` using the [`ZSerde`]. - pub fn into_mut<'a, T>(&'a mut self) -> T - where - ZSerde: Deserialize = &'a mut ZBytes, Error = Infallible>, - >::Error: Debug, - { - ZSerde.deserialize(self).unwrap_infallible() + #[cfg(all(feature = "shared-memory", feature = "unstable"))] + pub fn asz_shm(&self) -> Result<&zshm, ZDeserializeError> { + // A ZShm is expected to have only one slice + let mut zslices = self.0.zslices(); + if let Some(zs) = zslices.next() { + if let Some(shmb) = zs.downcast_ref::() { + return Ok(shmb.into()); + } + } + Err(ZDeserializeError) } -} - -/// A reader that implements [`std::io::Read`] trait to deserialize from a [`ZBytes`]. See [`ZBytesWriter`] for an example. -#[repr(transparent)] -#[derive(Debug)] -pub struct ZBytesReader<'a>(ZBufReader<'a>); - -#[derive(Debug)] -pub struct ReadError; -#[derive(Debug)] -pub enum ZReadOrDeserializeError -where - T: TryFrom, - >::Error: Debug, -{ - Read(ReadError), - Deserialize(>::Error), -} + #[cfg(all(feature = "shared-memory", feature = "unstable"))] + pub fn as_mut_zshm(&mut self) -> Result<&mut zshm, ZDeserializeError> { + // A ZSliceShmBorrowMut is expected to have only one slice + let mut zslices = self.0.zslices_mut(); + if let Some(zs) = zslices.next() { + // SAFETY: ShmBufInner cannot change the size of the slice + if let Some(shmb) = unsafe { zs.downcast_mut::() } { + return Ok(shmb.into()); + } + } + Err(ZDeserializeError) + } -impl std::fmt::Display for ZReadOrDeserializeError -where - T: Debug, - T: TryFrom, - >::Error: Debug, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ZReadOrDeserializeError::Read(_) => f.write_str("Read error"), - ZReadOrDeserializeError::Deserialize(e) => f.write_fmt(format_args!("{:?}", e)), + #[cfg(all(feature = "shared-memory", feature = "unstable"))] + pub fn as_zshm_mut(&mut self) -> Result<&mut zshmmut, ZDeserializeError> { + // A ZSliceShmBorrowMut is expected to have only one slice + let mut zslices = self.0.zslices_mut(); + if let Some(zs) = zslices.next() { + // SAFETY: ShmBufInner cannot change the size of the slice + if let Some(shmb) = unsafe { zs.downcast_mut::() } { + return shmb.try_into().or(Err(ZDeserializeError)); + } } + Err(ZDeserializeError) } } -impl std::error::Error for ZReadOrDeserializeError -where - T: Debug, - T: TryFrom, - >::Error: Debug, -{ -} +/// A reader that implements [`std::io::Read`] trait to read from a [`ZBytes`]. +#[repr(transparent)] +#[derive(Debug)] +pub struct ZBytesReader<'a>(ZBufReader<'a>); impl ZBytesReader<'_> { /// Returns the number of bytes that can still be read @@ -531,19 +504,20 @@ impl ZBytesReader<'_> { self.remaining() == 0 } + pub fn deserialize<'a, T: Deserialize<'a>>(&mut self) -> T { + self.try_deserialize().unwrap() + } + /// Deserialize an object of type `T` from a [`ZBytesReader`] using the [`ZSerde`]. /// See [`ZBytesWriter::serialize`] for an example. - pub fn deserialize(&mut self) -> Result>::Error> - where - for<'a> ZSerde: Deserialize = &'a ZBytes>, - >::Error: Debug, - { - let codec = Zenoh080::new(); - let abuf: ZBuf = codec.read(&mut self.0).unwrap(); - let apld = ZBytes::new(abuf); - - let a = ZSerde.deserialize(&apld)?; - Ok(a) + pub fn try_deserialize<'a, T: Deserialize<'a>>(&mut self) -> Result { + if T::FIXED_SIZE.is_some() { + T::read(self).map_err(Into::into) + } else { + let codec = Zenoh080::new(); + let buf: ZBuf = codec.read(&mut self.0).or(Err(ZDeserializeError))?; + T::try_from_zbytes(buf.into()) + } } } @@ -559,51 +533,20 @@ impl std::io::Seek for ZBytesReader<'_> { } } -/// A writer that implements [`std::io::Write`] trait to serialize into a [`ZBytes`]. -/// -/// Example: -/// ```rust -/// use zenoh::bytes::ZBytes; -/// -/// #[derive(Debug, PartialEq)] -/// struct Foo { -/// one: usize, -/// two: String, -/// three: Vec, -/// } -/// -/// let start = Foo { -/// one: 42, -/// two: String::from("Forty-Two"), -/// three: vec![42u8; 42], -/// }; -/// -/// let mut bytes = ZBytes::empty(); -/// let mut writer = bytes.writer(); -/// -/// writer.serialize(&start.one); -/// writer.serialize(&start.two); -/// writer.serialize(&start.three); -/// -/// let mut reader = bytes.reader(); -/// let end = Foo { -/// one: reader.deserialize().unwrap(), -/// two: reader.deserialize().unwrap(), -/// three: reader.deserialize().unwrap(), -/// }; -/// assert_eq!(start, end); -/// ``` +/// A writer that implements [`std::io::Write`] trait to write into a [`ZBytes`]. #[repr(transparent)] #[derive(Debug)] pub struct ZBytesWriter<'a>(ZBufWriter<'a>); impl ZBytesWriter<'_> { - fn write(&mut self, bytes: &ZBuf) { + fn write_serialized(&mut self, serialized: Serialized) { let codec = Zenoh080::new(); - // SAFETY: we are serializing slices on a ZBuf, so serialization will never - // fail unless we run out of memory. In that case, Rust memory allocator - // will panic before the serializer has any chance to fail. - unsafe { codec.write(&mut self.0, bytes).unwrap_unchecked() }; + // Result can be ignored because writing on `ZBufWriter` only fails if there + // is no bytes written. + let _ = match serialized { + Serialized::Slice(s) => codec.write(&mut self.0, s), + Serialized::ZBytes(zbytes) => codec.write(&mut self.0, &zbytes.0), + }; } /// Serialize a type `T` on the [`ZBytes`]. For simmetricity, every serialization @@ -615,7 +558,7 @@ impl ZBytesWriter<'_> { /// use zenoh::bytes::ZBytes; /// /// // serialization - /// let mut bytes = ZBytes::empty(); + /// let mut bytes = ZBytes::new(); /// let mut writer = bytes.writer(); /// let i1 = 1234_u32; /// let i2 = String::from("test"); @@ -632,23 +575,19 @@ impl ZBytesWriter<'_> { /// assert_eq!(i2, o2); /// assert_eq!(i3, o3); /// ``` - pub fn serialize(&mut self, t: T) - where - ZSerde: Serialize, - { - let tpld = ZSerde.serialize(t); - self.write(&tpld.0); + pub fn serialize<'a, T: Serialize<'a, Error = Infallible>>(&mut self, t: T) { + self.try_serialize(t).unwrap() } /// Try to serialize a type `T` on the [`ZBytes`]. Serialization works /// in the same way as [`ZBytesWriter::serialize`]. - pub fn try_serialize(&mut self, t: T) -> Result<(), E> - where - ZSerde: Serialize>, - { - let tpld = ZSerde.serialize(t)?; - self.write(&tpld.0); - Ok(()) + pub fn try_serialize<'a, T: Serialize<'a>>(&mut self, t: T) -> Result<(), T::Error> { + if T::FIXED_SIZE.is_some() { + t.write(self) + } else { + self.write_serialized(t.serialize()?); + Ok(()) + } } /// Append a [`ZBytes`] to this [`ZBytes`] by taking ownership. @@ -666,7 +605,7 @@ impl ZBytesWriter<'_> { /// let two = ZBytes::from(vec![2, 3, 4, 5]); /// let three = ZBytes::from(vec![6, 7]); /// - /// let mut bytes = ZBytes::empty(); + /// let mut bytes = ZBytes::new(); /// let mut writer = bytes.writer(); /// // Append data without copying by passing ownership /// writer.append(one); @@ -685,6 +624,10 @@ impl ZBytesWriter<'_> { unsafe { self.0.write_zslice(s).unwrap_unchecked() } } } + + pub fn reserve(&mut self, additional: usize) { + self.0.reserve(additional) + } } impl std::io::Write for ZBytesWriter<'_> { @@ -698,32 +641,6 @@ impl std::io::Write for ZBytesWriter<'_> { } /// An iterator that implements [`std::iter::Iterator`] trait to iterate on [`&[u8]`]. -/// -/// Example: -/// ```rust -/// use std::io::Write; -/// use zenoh::bytes::ZBytes; -/// -/// let buf1: Vec = vec![1, 2, 3]; -/// let buf2: Vec = vec![4, 5, 6, 7, 8]; -/// let mut zbs = ZBytes::empty(); -/// let mut writer = zbs.writer(); -/// writer.write(&buf1); -/// writer.write(&buf2); -/// -/// // Access the raw content -/// for slice in zbs.slices() { -/// println!("{:02x?}", slice); -/// } -/// -/// // Concatenate input in a single vector -/// let buf: Vec = buf1.into_iter().chain(buf2.into_iter()).collect(); -/// // Concatenate raw bytes in a single vector -/// let out: Vec = zbs.slices().fold(Vec::new(), |mut b, x| { b.extend_from_slice(x); b }); -/// // The previous line is the equivalent of -/// // let out: Vec = zbs.into(); -/// assert_eq!(buf, out); -/// ``` #[repr(transparent)] #[derive(Debug)] pub struct ZBytesSliceIterator<'a>(ZBytesSliceIteratorInner<'a>); @@ -742,73 +659,49 @@ impl<'a> Iterator for ZBytesSliceIterator<'a> { /// An iterator that implements [`std::iter::Iterator`] trait to iterate on values `T` in a [`ZBytes`]. /// Note that [`ZBytes`] contains a serialized version of `T` and iterating over a [`ZBytes`] performs lazy deserialization. -/// -/// Example: -/// ```rust -/// use zenoh::bytes::ZBytes; -/// -/// let list: Vec = vec![1.1, 2.2, 3.3]; -/// let mut zbs = ZBytes::from_iter(list.iter()); -/// -/// for (index, elem) in zbs.iter::().enumerate() { -/// assert_eq!(list[index], elem.unwrap()); -/// } -/// ``` #[repr(transparent)] #[derive(Debug)] pub struct ZBytesIterator<'a, T> { - reader: ZBufReader<'a>, + reader: ZBytesReader<'a>, _t: PhantomData, } -impl Iterator for ZBytesIterator<'_, T> -where - for<'a> ZSerde: Deserialize = &'a ZBytes>, - >::Error: Debug, -{ - type Item = Result>::Error>; +impl<'a, T: Deserialize<'a>> Iterator for ZBytesIterator<'_, T> { + type Item = Result; fn next(&mut self) -> Option { - let codec = Zenoh080::new(); - - let kbuf: ZBuf = codec.read(&mut self.reader).ok()?; - let kpld = ZBytes::new(kbuf); - - Some(ZSerde.deserialize(&kpld)) + Some(if T::FIXED_SIZE.is_some() { + if self.reader.is_empty() { + return None; + } + T::read(&mut self.reader).map_err(Into::into) + } else { + let codec = Zenoh080::new(); + let buf: ZBuf = codec.read(&mut self.reader.0).ok()?; + T::try_from_zbytes(buf.into()) + }) } } -impl FromIterator for ZBytes -where - ZSerde: Serialize, -{ +impl<'a, A: Serialize<'a, Error = Infallible>> FromIterator for ZBytes { fn from_iter>(iter: T) -> Self { - let mut bytes = ZBytes::empty(); + let iter = iter.into_iter(); + let mut bytes = ZBytes::new(); let mut writer = bytes.writer(); - for t in iter { - writer.serialize(t); + if let Some(size) = A::FIXED_SIZE { + writer.reserve(size * iter.size_hint().0); + for t in iter { + t.write(&mut writer).unwrap(); + } + } else { + for t in iter { + writer.write_serialized(t.serialize().unwrap()); + } } - - ZBytes::new(bytes) + bytes } } -/// The default serializer for [`ZBytes`]. It supports primitives types, such as: `Vec`, `uX`, `iX`, `fX`, `String`, `bool`. -/// It also supports common Rust serde values like [`serde_json::Value`]. See [`ZBytes`] for examples. -/// -/// **NOTE 1:** Zenoh semantic and protocol take care of sending and receiving bytes without restricting the actual data types. -/// -/// **NOTE 2:** [`ZSerde`] is the default serializer/deserializer provided for convenience to the users to deal with primitives data types via -/// a simple out-of-the-box encoding. That is, [`ZSerde`] is provided as a facilitator for simple use cases that need to send/receive data -/// over Zenoh, and doing so potentially to/from different programming languages. Make simple use cases simple and provide freedom for more -/// advanced use cases. -/// -/// **NOTE 3:** [`ZSerde`] is **NOT** by any means the only serializer/deserializer users can use nor a limitation to the types supported by Zenoh. -/// [`ZSerde`] does not have the ambition nor the plan to be a full alternative of more complete seriliazation libraries like *serde*, *protobuf*, -/// *bincode*, *flatbuffers*, etc. Users are free and encouraged to use any serializer/deserializer of their choice that better suits their use case. -#[derive(Clone, Copy, Debug)] -pub struct ZSerde; - #[derive(Debug, Clone, Copy)] pub struct ZDeserializeError; @@ -819,2538 +712,831 @@ impl std::fmt::Display for ZDeserializeError { } impl std::error::Error for ZDeserializeError {} - -// ZBytes -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: ZBytes) -> Self::Output { - t +impl From for ZDeserializeError { + fn from(_value: DidntRead) -> Self { + Self } } -impl From<&ZBytes> for ZBytes { - fn from(t: &ZBytes) -> Self { - ZSerde.serialize(t) +// ZBytes +impl SerializedSize for ZBytes {} +impl<'a> Serialize<'a> for ZBytes { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl From<&mut ZBytes> for ZBytes { - fn from(t: &mut ZBytes) -> Self { - ZSerde.serialize(t) + fn serialize(self) -> Result, Self::Error> { + Ok(self.into()) } } - -impl Serialize<&ZBytes> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &ZBytes) -> Self::Output { - t.clone() +impl<'a> Serialize<'a> for &ZBytes { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl Serialize<&mut ZBytes> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut ZBytes) -> Self::Output { - t.clone() + fn serialize(self) -> Result, Self::Error> { + self.clone().serialize() } } - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = Infallible; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - Ok(v.clone()) +impl Deserialize<'_> for ZBytes { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() + } + fn deserialize(zbytes: &'_ ZBytes) -> Result { + Ok(zbytes.clone()) + } + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Ok(zbytes) } } // ZBuf -#[doc(hidden)] -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: ZBuf) -> Self::Output { - ZBytes::new(t) +impl SerializedSize for ZBuf {} +impl<'a> Serialize<'a> for ZBuf { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -#[doc(hidden)] -impl From for ZBytes { - fn from(t: ZBuf) -> Self { - ZSerde.serialize(t) + fn serialize(self) -> Result, Self::Error> { + Ok(ZBytes::from(self).into()) } } - -#[doc(hidden)] -impl Serialize<&ZBuf> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &ZBuf) -> Self::Output { - ZBytes::new(t.clone()) +impl<'a> Serialize<'a> for &ZBuf { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -#[doc(hidden)] -impl From<&ZBuf> for ZBytes { - fn from(t: &ZBuf) -> Self { - ZSerde.serialize(t) + fn serialize(self) -> Result, Self::Error> { + self.clone().serialize() } } - -#[doc(hidden)] -impl Serialize<&mut ZBuf> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut ZBuf) -> Self::Output { - ZBytes::new(t.clone()) +impl Deserialize<'_> for ZBuf { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() } -} - -#[doc(hidden)] -impl From<&mut ZBuf> for ZBytes { - fn from(t: &mut ZBuf) -> Self { - ZSerde.serialize(t) + fn deserialize(zbytes: &'_ ZBytes) -> Result { + Ok(zbytes.clone().0) + } + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Ok(zbytes.0) } } - -#[doc(hidden)] -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = Infallible; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - Ok(v.0.clone()) +impl From for ZBytes { + fn from(value: ZBuf) -> Self { + Self(value) } } - -#[doc(hidden)] impl From for ZBuf { fn from(value: ZBytes) -> Self { value.0 } } -#[doc(hidden)] -impl From<&ZBytes> for ZBuf { - fn from(value: &ZBytes) -> Self { - ZSerde.deserialize(value).unwrap_infallible() +// ZSlice +impl SerializedSize for ZSlice {} +impl<'a> Serialize<'a> for ZSlice { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + Ok(ZBytes::from(self).into()) } } - -#[doc(hidden)] -impl From<&mut ZBytes> for ZBuf { - fn from(value: &mut ZBytes) -> Self { - ZSerde.deserialize(&*value).unwrap_infallible() +impl<'a> Serialize<'a> for &ZSlice { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + self.clone().serialize() } } - -// ZSlice -#[doc(hidden)] -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: ZSlice) -> Self::Output { - ZBytes::new(t) +impl Deserialize<'_> for ZSlice { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() + } + fn deserialize(zbytes: &'_ ZBytes) -> Result { + Ok(zbytes.0.to_zslice()) + } + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Self::deserialize(&zbytes) } } - -#[doc(hidden)] impl From for ZBytes { - fn from(t: ZSlice) -> Self { - ZSerde.serialize(t) + fn from(value: ZSlice) -> Self { + ZBytes(value.into()) } } -#[doc(hidden)] -impl Serialize<&ZSlice> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &ZSlice) -> Self::Output { - ZBytes::new(t.clone()) - } +// [u8; N] +impl SerializedSize for [u8; N] { + const FIXED_SIZE: Option = Some(N); } - -#[doc(hidden)] -impl From<&ZSlice> for ZBytes { - fn from(t: &ZSlice) -> Self { - ZSerde.serialize(t) +impl<'a, const N: usize> Serialize<'a> for [u8; N] { + type Error = Infallible; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + std::io::Write::write(writer, &self).unwrap(); + Ok(()) + } + fn serialize(self) -> Result, Self::Error> { + unimplemented!() } } - -#[doc(hidden)] -impl Serialize<&mut ZSlice> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut ZSlice) -> Self::Output { - ZBytes::new(t.clone()) +impl Deserialize<'_> for [u8; N] { + fn read(reader: &mut ZBytesReader) -> Result { + let mut buf = [0; N]; + std::io::Read::read_exact(reader, &mut buf).or(Err(ZDeserializeError))?; + Ok(buf) + } + fn deserialize(_zbytes: &'_ ZBytes) -> Result { + unimplemented!() + } + fn try_from_zbytes(_zbytes: ZBytes) -> Result { + unimplemented!() } } - -#[doc(hidden)] -impl From<&mut ZSlice> for ZBytes { - fn from(t: &mut ZSlice) -> Self { - ZSerde.serialize(t) +impl From<[u8; N]> for ZBytes { + fn from(value: [u8; N]) -> Self { + ZBytes(value.into()) } } -#[doc(hidden)] -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; +// Vec +impl SerializedSize for Vec {} +impl<'a> Serialize<'a> for Vec { type Error = Infallible; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - Ok(v.0.to_zslice()) + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -#[doc(hidden)] -impl From for ZSlice { - fn from(value: ZBytes) -> Self { - ZBuf::from(value).to_zslice() + fn serialize(self) -> Result, Self::Error> { + Ok(ZBytes::from(self).into()) } } - -#[doc(hidden)] -impl From<&ZBytes> for ZSlice { - fn from(value: &ZBytes) -> Self { - ZSerde.deserialize(value).unwrap_infallible() +impl<'a> Serialize<'a> for &'a Vec { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -#[doc(hidden)] -impl From<&mut ZBytes> for ZSlice { - fn from(value: &mut ZBytes) -> Self { - ZSerde.deserialize(&*value).unwrap_infallible() + fn serialize(self) -> Result, Self::Error> { + Ok(self.as_slice().into()) } } - -// [u8; N] -impl Serialize<[u8; N]> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: [u8; N]) -> Self::Output { - ZBytes::new(t) +impl Deserialize<'_> for Vec { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() + } + fn deserialize(zbytes: &'_ ZBytes) -> Result { + Ok(zbytes.0.contiguous().into()) + } + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Self::deserialize(&zbytes) } } - -impl From<[u8; N]> for ZBytes { - fn from(t: [u8; N]) -> Self { - ZSerde.serialize(t) +impl From> for ZBytes { + fn from(value: Vec) -> Self { + ZBytes(value.into()) } } -impl Serialize<&[u8; N]> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &[u8; N]) -> Self::Output { - ZBytes::new(*t) +// &[u8] +impl SerializedSize for &[u8] {} +impl<'a> Serialize<'a> for &'a [u8] { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + Ok(self.into()) } } - -impl From<&[u8; N]> for ZBytes { - fn from(t: &[u8; N]) -> Self { - ZSerde.serialize(t) +impl From<&[u8]> for ZBytes { + fn from(value: &[u8]) -> Self { + ZBytes::serialize(value) } } -impl Serialize<&mut [u8; N]> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut [u8; N]) -> Self::Output { - ZBytes::new(*t) +// Cow<[u8]> +impl SerializedSize for Cow<'_, [u8]> {} +impl<'a> Serialize<'a> for Cow<'a, [u8]> { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + Ok(match self { + Cow::Borrowed(s) => Serialized::Slice(s), + Cow::Owned(vec) => Serialized::ZBytes(vec.into()), + }) } } - -impl From<&mut [u8; N]> for ZBytes { - fn from(t: &mut [u8; N]) -> Self { - ZSerde.serialize(*t) +impl<'a> Serialize<'a> for &'a Cow<'a, [u8]> { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + Ok(self.as_ref().into()) } } - -impl Deserialize<[u8; N]> for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = ZDeserializeError; - - fn deserialize(self, v: Self::Input<'_>) -> Result<[u8; N], Self::Error> { - use std::io::Read; - - if v.0.len() != N { - return Err(ZDeserializeError); - } - let mut dst = [0u8; N]; - let mut reader = v.reader(); - reader.read_exact(&mut dst).map_err(|_| ZDeserializeError)?; - Ok(dst) +impl<'a> Deserialize<'a> for Cow<'a, [u8]> { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() } -} - -impl TryFrom for [u8; N] { - type Error = ZDeserializeError; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) + fn deserialize(zbytes: &'a ZBytes) -> Result { + Ok(zbytes.0.contiguous()) } -} - -impl TryFrom<&ZBytes> for [u8; N] { - type Error = ZDeserializeError; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Vec::try_from_zbytes(zbytes).map(Cow::Owned) } } - -impl TryFrom<&mut ZBytes> for [u8; N] { - type Error = ZDeserializeError; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) +impl From> for ZBytes { + fn from(value: Cow<'_, [u8]>) -> Self { + ZBytes::serialize(value) } } -// Vec -impl Serialize> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: Vec) -> Self::Output { - ZBytes::new(t) +// String +impl SerializedSize for String {} +impl<'a> Serialize<'a> for String { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl From> for ZBytes { - fn from(t: Vec) -> Self { - ZSerde.serialize(t) + fn serialize(self) -> Result, Self::Error> { + self.into_bytes().serialize() } } - -impl Serialize<&Vec> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &Vec) -> Self::Output { - ZBytes::new(t.clone()) +impl<'a> Serialize<'a> for &'a String { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl From<&Vec> for ZBytes { - fn from(t: &Vec) -> Self { - ZSerde.serialize(t) + fn serialize(self) -> Result, Self::Error> { + self.as_bytes().serialize() } } - -impl Serialize<&mut Vec> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut Vec) -> Self::Output { - ZBytes::new(t.clone()) +impl Deserialize<'_> for String { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() } -} - -impl From<&mut Vec> for ZBytes { - fn from(t: &mut Vec) -> Self { - ZSerde.serialize(t) + fn deserialize(zbytes: &'_ ZBytes) -> Result { + String::from_utf8(>::deserialize(zbytes)?).or(Err(ZDeserializeError)) } -} - -impl Deserialize> for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = Infallible; - - fn deserialize(self, v: Self::Input<'_>) -> Result, Self::Error> { - Ok(v.0.contiguous().to_vec()) + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Self::deserialize(&zbytes) } } - -impl From for Vec { - fn from(value: ZBytes) -> Self { - ZSerde.deserialize(&value).unwrap_infallible() +// &[u8] +impl SerializedSize for &str {} +impl<'a> Serialize<'a> for &'a str { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl From<&ZBytes> for Vec { - fn from(value: &ZBytes) -> Self { - ZSerde.deserialize(value).unwrap_infallible() + fn serialize(self) -> Result, Self::Error> { + Ok(self.as_bytes().into()) } } -impl From<&mut ZBytes> for Vec { - fn from(value: &mut ZBytes) -> Self { - ZSerde.deserialize(&*value).unwrap_infallible() +// Cow<[u8]> +impl SerializedSize for Cow<'_, str> {} +impl<'a> Serialize<'a> for Cow<'a, str> { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -// &[u8] -impl Serialize<&[u8]> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &[u8]) -> Self::Output { - ZBytes::new(t.to_vec()) + fn serialize(self) -> Result, Self::Error> { + Ok(match self { + Cow::Borrowed(s) => Serialized::Slice(s.as_bytes()), + Cow::Owned(vec) => Serialized::ZBytes(vec.into_bytes().into()), + }) } } - -impl From<&[u8]> for ZBytes { - fn from(t: &[u8]) -> Self { - ZSerde.serialize(t) +impl<'a> Serialize<'a> for &'a Cow<'a, str> { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl Serialize<&mut [u8]> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut [u8]) -> Self::Output { - ZSerde.serialize(&*t) + fn serialize(self) -> Result, Self::Error> { + Ok(self.as_bytes().into()) } } - -impl From<&mut [u8]> for ZBytes { - fn from(t: &mut [u8]) -> Self { - ZSerde.serialize(t) +impl<'a> Deserialize<'a> for Cow<'a, str> { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() } -} - -// Cow<[u8]> -impl<'a> Serialize> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: Cow<'a, [u8]>) -> Self::Output { - ZBytes::new(t.to_vec()) + fn deserialize(zbytes: &'a ZBytes) -> Result { + Ok(match >::deserialize(zbytes)? { + Cow::Borrowed(s) => std::str::from_utf8(s).or(Err(ZDeserializeError))?.into(), + Cow::Owned(vec) => String::from_utf8(vec).or(Err(ZDeserializeError))?.into(), + }) } -} - -impl From> for ZBytes { - fn from(t: Cow<'_, [u8]>) -> Self { - ZSerde.serialize(t) + fn try_from_zbytes(zbytes: ZBytes) -> Result { + String::try_from_zbytes(zbytes).map(Cow::Owned) } } -impl<'a> Serialize<&Cow<'a, [u8]>> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &Cow<'a, [u8]>) -> Self::Output { - ZBytes::new(t.to_vec()) - } +// numeric +macro_rules! impl_num { + ($($ty:ty),* $(,)?) => {$( + impl SerializedSize for $ty { + const FIXED_SIZE: Option = Some(size_of::<$ty>()); + } + impl<'a> Serialize<'a> for $ty { + type Error = Infallible; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + self.to_le_bytes().write(writer) + } + fn serialize(self) -> Result, Self::Error> { + unimplemented!() + } + } + impl<'a> Serialize<'a> for &$ty { + type Error = Infallible; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + (*self).to_le_bytes().write(writer) + } + fn serialize(self) -> Result, Self::Error> { + unimplemented!() + } + } + impl Deserialize<'_> for $ty { + fn read(reader: &mut ZBytesReader) -> Result { + <[u8; {size_of::<$ty>()}]>::read(reader).map(<$ty>::from_le_bytes) + } + fn deserialize(_zbytes: &'_ ZBytes) -> Result { + unimplemented!() + } + fn try_from_zbytes(_zbytes: ZBytes) -> Result { + unimplemented!() + } + } + )*}; } +impl_num!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64); -impl From<&Cow<'_, [u8]>> for ZBytes { - fn from(t: &Cow<'_, [u8]>) -> Self { - ZSerde.serialize(t) - } +impl SerializedSize for bool { + const FIXED_SIZE: Option = Some(size_of::()); } - -impl<'a> Serialize<&mut Cow<'a, [u8]>> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut Cow<'a, [u8]>) -> Self::Output { - ZSerde.serialize(&*t) +impl<'a> Serialize<'a> for bool { + type Error = Infallible; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + (self as u8).write(writer) } -} - -impl From<&mut Cow<'_, [u8]>> for ZBytes { - fn from(t: &mut Cow<'_, [u8]>) -> Self { - ZSerde.serialize(t) + fn serialize(self) -> Result, Self::Error> { + unimplemented!() } } - -impl<'a> Deserialize> for ZSerde { - type Input<'b> = &'a ZBytes; +impl<'a> Serialize<'a> for &bool { type Error = Infallible; - - fn deserialize(self, v: Self::Input<'a>) -> Result, Self::Error> { - Ok(v.0.contiguous()) + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + (*self as u8).write(writer) + } + fn serialize(self) -> Result, Self::Error> { + unimplemented!() } } - -impl From for Cow<'static, [u8]> { - fn from(v: ZBytes) -> Self { - match v.0.contiguous() { - Cow::Borrowed(s) => Cow::Owned(s.to_vec()), - Cow::Owned(s) => Cow::Owned(s), +impl Deserialize<'_> for bool { + fn read(reader: &mut ZBytesReader) -> Result { + match u8::read(reader)? { + 0 => Ok(false), + 1 => Ok(true), + _ => Err(ZDeserializeError), } } -} - -impl<'a> From<&'a ZBytes> for Cow<'a, [u8]> { - fn from(value: &'a ZBytes) -> Self { - ZSerde.deserialize(value).unwrap_infallible() + fn deserialize(_zbytes: &'_ ZBytes) -> Result { + unimplemented!() } -} - -impl<'a> From<&'a mut ZBytes> for Cow<'a, [u8]> { - fn from(value: &'a mut ZBytes) -> Self { - ZSerde.deserialize(&*value).unwrap_infallible() + fn try_from_zbytes(_zbytes: ZBytes) -> Result { + unimplemented!() } } -// String -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: String) -> Self::Output { - ZBytes::new(s.into_bytes()) - } +// char +impl SerializedSize for char { + const FIXED_SIZE: Option = Some(size_of::()); } - -impl From for ZBytes { - fn from(t: String) -> Self { - ZSerde.serialize(t) +impl<'a> Serialize<'a> for char { + type Error = Infallible; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + u32::from(self).write(writer) } -} - -impl Serialize<&String> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &String) -> Self::Output { - ZBytes::new(s.clone().into_bytes()) + fn serialize(self) -> Result, Self::Error> { + unimplemented!() } } - -impl From<&String> for ZBytes { - fn from(t: &String) -> Self { - ZSerde.serialize(t) +impl<'a> Serialize<'a> for &char { + type Error = Infallible; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + u32::from(*self).write(writer) } -} - -impl Serialize<&mut String> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &mut String) -> Self::Output { - ZSerde.serialize(&*s) + fn serialize(self) -> Result, Self::Error> { + unimplemented!() } } - -impl From<&mut String> for ZBytes { - fn from(t: &mut String) -> Self { - ZSerde.serialize(t) +impl Deserialize<'_> for char { + fn read(reader: &mut ZBytesReader) -> Result { + u32::read(reader)?.try_into().or(Err(ZDeserializeError)) } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = FromUtf8Error; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - let v: Vec = ZSerde.deserialize(v).unwrap_infallible(); - String::from_utf8(v) + fn deserialize(_zbytes: &'_ ZBytes) -> Result { + unimplemented!() } -} - -impl TryFrom for String { - type Error = FromUtf8Error; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) + fn try_from_zbytes(_zbytes: ZBytes) -> Result { + unimplemented!() } } -impl TryFrom<&ZBytes> for String { - type Error = FromUtf8Error; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) +/* Zenoh advanced types serializer/deserializer */ +// Parameters +impl SerializedSize for Parameters<'_> {} +impl<'a> Serialize<'a> for Parameters<'a> { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl TryFrom<&mut ZBytes> for String { - type Error = FromUtf8Error; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) + fn serialize(self) -> Result, Self::Error> { + >::from(self).serialize() } } - -// &str -impl Serialize<&str> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &str) -> Self::Output { - ZSerde.serialize(s.to_string()) +impl<'a> Serialize<'a> for &'a Parameters<'a> { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl From<&str> for ZBytes { - fn from(t: &str) -> Self { - ZSerde.serialize(t) + fn serialize(self) -> Result, Self::Error> { + Ok(self.as_str().as_bytes().into()) } } - -impl Serialize<&mut str> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &mut str) -> Self::Output { - ZSerde.serialize(&*s) +impl<'a> Deserialize<'a> for Parameters<'a> { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() } -} - -impl From<&mut str> for ZBytes { - fn from(t: &mut str) -> Self { - ZSerde.serialize(t) + fn deserialize(zbytes: &'a ZBytes) -> Result { + >::deserialize(zbytes).map(Into::into) } -} - -impl<'a> Serialize> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: Cow<'a, str>) -> Self::Output { - Self.serialize(s.to_string()) + fn try_from_zbytes(zbytes: ZBytes) -> Result { + String::try_from_zbytes(zbytes).map(Into::into) } } -impl From> for ZBytes { - fn from(t: Cow<'_, str>) -> Self { - ZSerde.serialize(t) +// Timestamp +impl SerializedSize for Timestamp {} +impl<'a> Serialize<'a> for Timestamp { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + (&self).serialize() } } - -impl<'a> Serialize<&Cow<'a, str>> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &Cow<'a, str>) -> Self::Output { - ZSerde.serialize(s.to_string()) +impl<'a> Serialize<'a> for &Timestamp { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + let codec = Zenoh080::new(); + let mut buffer = ZBuf::empty(); + let mut writer = buffer.writer(); + // Result can be ignored because writing on `ZBufWriter` only fails if there + // is no bytes written. + let _ = codec.write(&mut writer, self); + Ok(ZBytes::from(buffer).into()) } } - -impl From<&Cow<'_, str>> for ZBytes { - fn from(t: &Cow<'_, str>) -> Self { - ZSerde.serialize(t) +impl Deserialize<'_> for Timestamp { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() + } + fn deserialize(zbytes: &'_ ZBytes) -> Result { + let codec = Zenoh080::new(); + let mut reader = zbytes.0.reader(); + codec.read(&mut reader).or(Err(ZDeserializeError)) + } + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Self::deserialize(&zbytes) } } -impl<'a> Serialize<&mut Cow<'a, str>> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &mut Cow<'a, str>) -> Self::Output { - ZSerde.serialize(&*s) +// Encoding +impl SerializedSize for Encoding {} +impl<'a> Serialize<'a> for Encoding { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + let encoding: EncodingProto = self.into(); + let codec = Zenoh080::new(); + let mut buffer = ZBuf::empty(); + let mut writer = buffer.writer(); + // Result can be ignored because writing on `ZBufWriter` only fails if there + // is no bytes written. + let _ = codec.write(&mut writer, &encoding); + Ok(ZBytes::from(buffer).into()) } } - -impl From<&mut Cow<'_, str>> for ZBytes { - fn from(t: &mut Cow<'_, str>) -> Self { - ZSerde.serialize(t) +impl<'a> Serialize<'a> for &Encoding { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + self.clone().serialize() } } - -/// See [`Deserialize>`] for guarantees on copies. -impl<'a> Deserialize> for ZSerde { - type Input<'b> = &'a ZBytes; - type Error = Utf8Error; - - fn deserialize(self, v: Self::Input<'a>) -> Result, Self::Error> { - Cow::try_from(v) +impl Deserialize<'_> for Encoding { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() + } + fn deserialize(zbytes: &'_ ZBytes) -> Result { + let codec = Zenoh080::new(); + let mut reader = zbytes.0.reader(); + let encoding: EncodingProto = codec.read(&mut reader).or(Err(ZDeserializeError))?; + Ok(encoding.into()) + } + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Self::deserialize(&zbytes) } } -impl TryFrom for Cow<'static, str> { - type Error = Utf8Error; - - fn try_from(v: ZBytes) -> Result { - Ok(match Cow::<[u8]>::from(v) { - Cow::Borrowed(s) => core::str::from_utf8(s)?.into(), - Cow::Owned(s) => String::from_utf8(s).map_err(|err| err.utf8_error())?.into(), - }) +// Value +impl SerializedSize for Value {} +impl<'a> Serialize<'a> for Value { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + (self.payload, self.encoding).serialize() } } - -impl<'a> TryFrom<&'a ZBytes> for Cow<'a, str> { - type Error = Utf8Error; - - fn try_from(v: &'a ZBytes) -> Result { - Ok(match Cow::<[u8]>::from(v) { - Cow::Borrowed(s) => core::str::from_utf8(s)?.into(), - Cow::Owned(s) => String::from_utf8(s).map_err(|err| err.utf8_error())?.into(), - }) +impl<'a> Serialize<'a> for &Value { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + (&self.payload, &self.encoding).serialize() } } - -impl<'a> TryFrom<&'a mut ZBytes> for Cow<'a, str> { - type Error = Utf8Error; - - fn try_from(v: &'a mut ZBytes) -> Result { - Ok(match Cow::<[u8]>::from(v) { - Cow::Borrowed(s) => core::str::from_utf8(s)?.into(), - Cow::Owned(s) => String::from_utf8(s).map_err(|err| err.utf8_error())?.into(), - }) +impl Deserialize<'_> for Value { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() + } + fn deserialize(zbytes: &'_ ZBytes) -> Result { + let (payload, encoding) = <_>::deserialize(zbytes)?; + Ok(Value { payload, encoding }) + } + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Self::deserialize(&zbytes) } } -// - Impl Serialize/Deserialize for numbers -macro_rules! impl_num { - ($t:ty) => { - impl Serialize<$t> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: $t) -> Self::Output { - let bs = t.to_le_bytes(); - let mut end = 1; - if t != 0 as $t { - end += bs.iter().rposition(|b| *b != 0).unwrap_or(bs.len() - 1); - }; - // SAFETY: - // - 0 is a valid start index because bs is guaranteed to always have a length greater or equal than 1 - // - end is a valid end index because is bounded between 0 and bs.len() - ZBytes::new(unsafe { ZSlice::new(Arc::new(bs), 0, end).unwrap_unchecked() }) - } - } - - impl From<$t> for ZBytes { - fn from(t: $t) -> Self { - ZSerde.serialize(t) - } - } - - impl Serialize<&$t> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &$t) -> Self::Output { - Self.serialize(*t) - } - } - - impl From<&$t> for ZBytes { - fn from(t: &$t) -> Self { - ZSerde.serialize(t) +// JSON/YAML +macro_rules! impl_serde { + ($($package:ident),* $(,)?) => {$( + impl SerializedSize for $package::Value {} + impl<'a> Serialize<'a> for $package::Value { + type Error = $package::Error; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } - } - - impl Serialize<&mut $t> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut $t) -> Self::Output { - Self.serialize(*t) + fn serialize(self) -> Result, Self::Error> { + (&self).serialize() } } - - impl From<&mut $t> for ZBytes { - fn from(t: &mut $t) -> Self { - ZSerde.serialize(t) + impl<'a> Serialize<'a> for &$package::Value { + type Error = $package::Error; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } - } - - impl Deserialize<$t> for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = ZDeserializeError; - - fn deserialize(self, v: Self::Input<'_>) -> Result<$t, Self::Error> { - use std::io::Read; - - let mut r = v.reader(); - let mut bs = (0 as $t).to_le_bytes(); - if v.len() > bs.len() { - return Err(ZDeserializeError); - } - r.read_exact(&mut bs[..v.len()]) - .map_err(|_| ZDeserializeError)?; - let t = <$t>::from_le_bytes(bs); - Ok(t) + fn serialize(self) -> Result, Self::Error> { + let mut zbytes = ZBytes::new(); + $package::to_writer(zbytes.writer(), self)?; + Ok(zbytes.into()) } } - - impl TryFrom for $t { - type Error = ZDeserializeError; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) + impl Deserialize<'_> for $package::Value { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() } - } - - impl TryFrom<&ZBytes> for $t { - type Error = ZDeserializeError; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) + fn deserialize(zbytes: &'_ ZBytes) -> Result { + Ok($package::from_reader(zbytes.reader()).or(Err(ZDeserializeError))?) } - } - - impl TryFrom<&mut ZBytes> for $t { - type Error = ZDeserializeError; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Self::deserialize(&zbytes) } } - }; + )*}; } +impl_serde!(serde_json, serde_yaml); -// Zenoh unsigned integers -impl_num!(u8); -impl_num!(u16); -impl_num!(u32); -impl_num!(u64); -impl_num!(u128); -impl_num!(usize); - -// Zenoh signed integers -impl_num!(i8); -impl_num!(i16); -impl_num!(i32); -impl_num!(i64); -impl_num!(i128); -impl_num!(isize); - -// Zenoh floats -impl_num!(f32); -impl_num!(f64); - -// Zenoh bool -impl Serialize for ZSerde { - type Output = ZBytes; +// bytes::Bytes - fn serialize(self, t: bool) -> Self::Output { - // SAFETY: casting a bool into an integer is well-defined behaviour. - // 0 is false, 1 is true: https://doc.rust-lang.org/std/primitive.bool.html - ZBytes::new(ZBuf::from((t as u8).to_le_bytes())) +// Define a transparent wrapper type to get around Rust's orphan rule. +// This allows to use bytes::Bytes directly as supporting buffer of a +// ZSlice resulting in zero-copy and zero-alloc bytes::Bytes serialization. +#[repr(transparent)] +#[derive(Debug)] +struct BytesWrap(bytes::Bytes); +impl ZSliceBuffer for BytesWrap { + fn as_slice(&self) -> &[u8] { + &self.0 } -} - -impl From for ZBytes { - fn from(t: bool) -> Self { - ZSerde.serialize(t) + fn as_any(&self) -> &dyn std::any::Any { + self } -} - -impl Serialize<&bool> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &bool) -> Self::Output { - ZSerde.serialize(*t) + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { + self } } -impl From<&bool> for ZBytes { - fn from(t: &bool) -> Self { - ZSerde.serialize(t) +impl SerializedSize for bytes::Bytes {} +impl<'a> Serialize<'a> for bytes::Bytes { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl Serialize<&mut bool> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut bool) -> Self::Output { - ZSerde.serialize(*t) + fn serialize(self) -> Result, Self::Error> { + Ok(ZBytes::from(self).into()) } } - -impl From<&mut bool> for ZBytes { - fn from(t: &mut bool) -> Self { - ZSerde.serialize(t) +impl<'a> Serialize<'a> for &bytes::Bytes { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = ZDeserializeError; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - let p = v.deserialize::().map_err(|_| ZDeserializeError)?; - match p { - 0 => Ok(false), - 1 => Ok(true), - _ => Err(ZDeserializeError), - } + fn serialize(self) -> Result, Self::Error> { + self.clone().serialize() } } - -impl TryFrom for bool { - type Error = ZDeserializeError; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) +impl Deserialize<'_> for bytes::Bytes { + fn read(_reader: &mut ZBytesReader) -> Result { + unimplemented!() } -} - -impl TryFrom<&ZBytes> for bool { - type Error = ZDeserializeError; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) + fn deserialize(zbytes: &'_ ZBytes) -> Result { + // bytes::Bytes can be constructed only by passing ownership to the constructor. + // Thereofore, here we are forced to allocate a vector and copy the whole ZBytes + // content since bytes::Bytes does not support anything else than Box (and its + // variants like Vec and String). + Ok(bytes::Bytes::from(>::deserialize(zbytes)?)) } -} - -impl TryFrom<&mut ZBytes> for bool { - type Error = ZDeserializeError; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) + fn try_from_zbytes(zbytes: ZBytes) -> Result { + Self::deserialize(&zbytes) } } - -// Zenoh char -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: char) -> Self::Output { - // We can convert char to u32 and encode it as such - // See https://doc.rust-lang.org/std/primitive.char.html#method.from_u32 - ZSerde.serialize(t as u32) +impl From for ZBytes { + fn from(value: bytes::Bytes) -> Self { + ZBytes(BytesWrap(value).into()) } } -impl From for ZBytes { - fn from(t: char) -> Self { - ZSerde.serialize(t) - } -} +// Shared memory +#[cfg(all(feature = "shared-memory", feature = "unstable"))] +mod shm { + use zenoh_shm::api::buffer::{zshm::ZShm, zshmmut::ZShmMut}; -impl Serialize<&char> for ZSerde { - type Output = ZBytes; + use super::*; - fn serialize(self, t: &char) -> Self::Output { - ZSerde.serialize(*t) + impl SerializedSize for ZShm {} + impl<'a> Serialize<'a> for ZShm { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() + } + fn serialize(self) -> Result, Self::Error> { + Ok(ZBytes::from(self).into()) + } } -} - -impl From<&char> for ZBytes { - fn from(t: &char) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&mut char> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut char) -> Self::Output { - ZSerde.serialize(*t) - } -} - -impl From<&mut char> for ZBytes { - fn from(t: &mut char) -> Self { - ZSerde.serialize(t) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = ZDeserializeError; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - let c = v.deserialize::()?; - let c = char::try_from(c).map_err(|_| ZDeserializeError)?; - Ok(c) - } -} - -impl TryFrom for char { - type Error = ZDeserializeError; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for char { - type Error = ZDeserializeError; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for char { - type Error = ZDeserializeError; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// - Zenoh advanced types serializer/deserializer -// Parameters -impl Serialize> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: Parameters<'_>) -> Self::Output { - Self.serialize(t.as_str()) - } -} - -impl From> for ZBytes { - fn from(t: Parameters<'_>) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&Parameters<'_>> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &Parameters<'_>) -> Self::Output { - Self.serialize(t.as_str()) - } -} - -impl<'s> From<&'s Parameters<'s>> for ZBytes { - fn from(t: &'s Parameters<'s>) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&mut Parameters<'_>> for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: &mut Parameters<'_>) -> Self::Output { - Self.serialize(t.as_str()) - } -} - -impl<'s> From<&'s mut Parameters<'s>> for ZBytes { - fn from(t: &'s mut Parameters<'s>) -> Self { - ZSerde.serialize(&*t) - } -} - -impl<'a> Deserialize> for ZSerde { - type Input<'b> = &'a ZBytes; - type Error = ZDeserializeError; - - fn deserialize(self, v: Self::Input<'a>) -> Result, Self::Error> { - let s = v - .deserialize::>() - .map_err(|_| ZDeserializeError)?; - Ok(Parameters::from(s)) - } -} - -impl TryFrom for Parameters<'static> { - type Error = ZDeserializeError; - - fn try_from(v: ZBytes) -> Result { - let s = v.deserialize::>().map_err(|_| ZDeserializeError)?; - Ok(Parameters::from(s.into_owned())) - } -} - -impl<'s> TryFrom<&'s ZBytes> for Parameters<'s> { - type Error = ZDeserializeError; - - fn try_from(value: &'s ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl<'s> TryFrom<&'s mut ZBytes> for Parameters<'s> { - type Error = ZDeserializeError; - - fn try_from(value: &'s mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// Timestamp -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: Timestamp) -> Self::Output { - ZSerde.serialize(&s) - } -} - -impl From for ZBytes { - fn from(t: Timestamp) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&Timestamp> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &Timestamp) -> Self::Output { - let codec = Zenoh080::new(); - let mut buffer = ZBuf::empty(); - let mut writer = buffer.writer(); - // SAFETY: we are serializing slices on a ZBuf, so serialization will never - // fail unless we run out of memory. In that case, Rust memory allocator - // will panic before the serializer has any chance to fail. - unsafe { - codec.write(&mut writer, s).unwrap_unchecked(); - } - ZBytes::from(buffer) - } -} - -impl From<&Timestamp> for ZBytes { - fn from(t: &Timestamp) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&mut Timestamp> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &mut Timestamp) -> Self::Output { - ZSerde.serialize(&*s) - } -} - -impl From<&mut Timestamp> for ZBytes { - fn from(t: &mut Timestamp) -> Self { - ZSerde.serialize(t) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = ReadError; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - let codec = Zenoh080::new(); - let mut reader = v.0.reader(); - let e: Timestamp = codec.read(&mut reader).map_err(|_| ReadError)?; - Ok(e) - } -} - -impl TryFrom for Timestamp { - type Error = ReadError; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for Timestamp { - type Error = ReadError; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for Timestamp { - type Error = ReadError; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// Encoding -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: Encoding) -> Self::Output { - let e: EncodingProto = s.into(); - let codec = Zenoh080::new(); - let mut buffer = ZBuf::empty(); - let mut writer = buffer.writer(); - // SAFETY: we are serializing slices on a ZBuf, so serialization will never - // fail unless we run out of memory. In that case, Rust memory allocator - // will panic before the serializer has any chance to fail. - unsafe { - codec.write(&mut writer, &e).unwrap_unchecked(); - } - ZBytes::from(buffer) - } -} - -impl From for ZBytes { - fn from(t: Encoding) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&Encoding> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &Encoding) -> Self::Output { - ZSerde.serialize(s.clone()) - } -} - -impl From<&Encoding> for ZBytes { - fn from(t: &Encoding) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&mut Encoding> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &mut Encoding) -> Self::Output { - ZSerde.serialize(&*s) - } -} - -impl From<&mut Encoding> for ZBytes { - fn from(t: &mut Encoding) -> Self { - ZSerde.serialize(t) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = ReadError; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - let codec = Zenoh080::new(); - let mut reader = v.0.reader(); - let e: EncodingProto = codec.read(&mut reader).map_err(|_| ReadError)?; - Ok(e.into()) - } -} - -impl TryFrom for Encoding { - type Error = ReadError; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for Encoding { - type Error = ReadError; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for Encoding { - type Error = ReadError; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// Value -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: Value) -> Self::Output { - ZSerde.serialize((s.payload(), s.encoding())) - } -} - -impl From for ZBytes { - fn from(t: Value) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&Value> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &Value) -> Self::Output { - ZSerde.serialize(s.clone()) - } -} - -impl From<&Value> for ZBytes { - fn from(t: &Value) -> Self { - ZSerde.serialize(t) - } -} - -impl Serialize<&mut Value> for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: &mut Value) -> Self::Output { - ZSerde.serialize(&*s) - } -} - -impl From<&mut Value> for ZBytes { - fn from(t: &mut Value) -> Self { - ZSerde.serialize(t) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = ZReadOrDeserializeErrorTuple2; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - let (payload, encoding) = v.deserialize::<(ZBytes, Encoding)>()?; - Ok(Value::new(payload, encoding)) - } -} - -impl TryFrom for Value { - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for Value { - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for Value { - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// JSON -impl Serialize for ZSerde { - type Output = Result; - - fn serialize(self, t: serde_json::Value) -> Self::Output { - ZSerde.serialize(&t) - } -} - -impl TryFrom for ZBytes { - type Error = serde_json::Error; - - fn try_from(value: serde_json::Value) -> Result { - ZSerde.serialize(&value) - } -} - -impl Serialize<&serde_json::Value> for ZSerde { - type Output = Result; - - fn serialize(self, t: &serde_json::Value) -> Self::Output { - let mut bytes = ZBytes::empty(); - serde_json::to_writer(bytes.writer(), t)?; - Ok(bytes) - } -} - -impl TryFrom<&serde_json::Value> for ZBytes { - type Error = serde_json::Error; - - fn try_from(value: &serde_json::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Serialize<&mut serde_json::Value> for ZSerde { - type Output = Result; - - fn serialize(self, t: &mut serde_json::Value) -> Self::Output { - let mut bytes = ZBytes::empty(); - serde_json::to_writer(bytes.writer(), t)?; - Ok(bytes) - } -} - -impl TryFrom<&mut serde_json::Value> for ZBytes { - type Error = serde_json::Error; - - fn try_from(value: &mut serde_json::Value) -> Result { - ZSerde.serialize(&*value) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = serde_json::Error; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - serde_json::from_reader(v.reader()) - } -} - -impl TryFrom for serde_json::Value { - type Error = serde_json::Error; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for serde_json::Value { - type Error = serde_json::Error; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for serde_json::Value { - type Error = serde_json::Error; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// Yaml -impl Serialize for ZSerde { - type Output = Result; - - fn serialize(self, t: serde_yaml::Value) -> Self::Output { - Self.serialize(&t) - } -} - -impl TryFrom for ZBytes { - type Error = serde_yaml::Error; - - fn try_from(value: serde_yaml::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Serialize<&serde_yaml::Value> for ZSerde { - type Output = Result; - - fn serialize(self, t: &serde_yaml::Value) -> Self::Output { - let mut bytes = ZBytes::empty(); - serde_yaml::to_writer(bytes.writer(), t)?; - Ok(bytes) - } -} - -impl TryFrom<&serde_yaml::Value> for ZBytes { - type Error = serde_yaml::Error; - - fn try_from(value: &serde_yaml::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Serialize<&mut serde_yaml::Value> for ZSerde { - type Output = Result; - - fn serialize(self, t: &mut serde_yaml::Value) -> Self::Output { - let mut bytes = ZBytes::empty(); - serde_yaml::to_writer(bytes.writer(), t)?; - Ok(bytes) - } -} - -impl TryFrom<&mut serde_yaml::Value> for ZBytes { - type Error = serde_yaml::Error; - - fn try_from(value: &mut serde_yaml::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = serde_yaml::Error; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - serde_yaml::from_reader(v.reader()) - } -} - -impl TryFrom for serde_yaml::Value { - type Error = serde_yaml::Error; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for serde_yaml::Value { - type Error = serde_yaml::Error; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for serde_yaml::Value { - type Error = serde_yaml::Error; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// CBOR -impl Serialize for ZSerde { - type Output = Result; - - fn serialize(self, t: serde_cbor::Value) -> Self::Output { - Self.serialize(&t) - } -} - -impl TryFrom for ZBytes { - type Error = serde_cbor::Error; - - fn try_from(value: serde_cbor::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Serialize<&serde_cbor::Value> for ZSerde { - type Output = Result; - - fn serialize(self, t: &serde_cbor::Value) -> Self::Output { - let mut bytes = ZBytes::empty(); - serde_cbor::to_writer(bytes.0.writer(), t)?; - Ok(bytes) - } -} - -impl TryFrom<&serde_cbor::Value> for ZBytes { - type Error = serde_cbor::Error; - - fn try_from(value: &serde_cbor::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Serialize<&mut serde_cbor::Value> for ZSerde { - type Output = Result; - - fn serialize(self, t: &mut serde_cbor::Value) -> Self::Output { - ZSerde.serialize(&*t) - } -} - -impl TryFrom<&mut serde_cbor::Value> for ZBytes { - type Error = serde_cbor::Error; - - fn try_from(value: &mut serde_cbor::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = serde_cbor::Error; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - serde_cbor::from_reader(v.reader()) - } -} - -impl TryFrom for serde_cbor::Value { - type Error = serde_cbor::Error; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for serde_cbor::Value { - type Error = serde_cbor::Error; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for serde_cbor::Value { - type Error = serde_cbor::Error; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// Pickle -impl Serialize for ZSerde { - type Output = Result; - - fn serialize(self, t: serde_pickle::Value) -> Self::Output { - Self.serialize(&t) - } -} - -impl TryFrom for ZBytes { - type Error = serde_pickle::Error; - - fn try_from(value: serde_pickle::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Serialize<&serde_pickle::Value> for ZSerde { - type Output = Result; - - fn serialize(self, t: &serde_pickle::Value) -> Self::Output { - let mut bytes = ZBytes::empty(); - serde_pickle::value_to_writer( - &mut bytes.0.writer(), - t, - serde_pickle::SerOptions::default(), - )?; - Ok(bytes) - } -} - -impl TryFrom<&serde_pickle::Value> for ZBytes { - type Error = serde_pickle::Error; - - fn try_from(value: &serde_pickle::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Serialize<&mut serde_pickle::Value> for ZSerde { - type Output = Result; - - fn serialize(self, t: &mut serde_pickle::Value) -> Self::Output { - ZSerde.serialize(&*t) - } -} - -impl TryFrom<&mut serde_pickle::Value> for ZBytes { - type Error = serde_pickle::Error; - - fn try_from(value: &mut serde_pickle::Value) -> Result { - ZSerde.serialize(value) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = serde_pickle::Error; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - serde_pickle::value_from_reader(v.reader(), serde_pickle::DeOptions::default()) - } -} - -impl TryFrom for serde_pickle::Value { - type Error = serde_pickle::Error; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for serde_pickle::Value { - type Error = serde_pickle::Error; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for serde_pickle::Value { - type Error = serde_pickle::Error; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// bytes::Bytes - -// Define a transparent wrapper type to get around Rust's orphan rule. -// This allows to use bytes::Bytes directly as supporting buffer of a -// ZSlice resulting in zero-copy and zero-alloc bytes::Bytes serialization. -#[repr(transparent)] -#[derive(Debug)] -struct BytesWrap(bytes::Bytes); - -impl ZSliceBuffer for BytesWrap { - fn as_slice(&self) -> &[u8] { - &self.0 - } - - fn as_any(&self) -> &dyn std::any::Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn std::any::Any { - self - } -} - -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, s: bytes::Bytes) -> Self::Output { - ZBytes::new(BytesWrap(s)) - } -} - -impl From for ZBytes { - fn from(t: bytes::Bytes) -> Self { - ZSerde.serialize(t) - } -} - -impl Deserialize for ZSerde { - type Input<'a> = &'a ZBytes; - type Error = Infallible; - - fn deserialize(self, v: Self::Input<'_>) -> Result { - // bytes::Bytes can be constructed only by passing ownership to the constructor. - // Thereofore, here we are forced to allocate a vector and copy the whole ZBytes - // content since bytes::Bytes does not support anything else than Box (and its - // variants like Vec and String). - let v: Vec = ZSerde.deserialize(v).unwrap_infallible(); - Ok(bytes::Bytes::from(v)) - } -} - -impl TryFrom for bytes::Bytes { - type Error = Infallible; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for bytes::Bytes { - type Error = Infallible; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for bytes::Bytes { - type Error = Infallible; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// Shared memory conversion -#[cfg(feature = "shared-memory")] -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: ZShm) -> Self::Output { - let slice: ZSlice = t.into(); - ZBytes::new(slice) - } -} - -#[cfg(feature = "shared-memory")] -impl From for ZBytes { - fn from(t: ZShm) -> Self { - ZSerde.serialize(t) - } -} - -// Shared memory conversion -#[cfg(feature = "shared-memory")] -impl Serialize for ZSerde { - type Output = ZBytes; - - fn serialize(self, t: ZShmMut) -> Self::Output { - let slice: ZSlice = t.into(); - ZBytes::new(slice) - } -} - -#[cfg(feature = "shared-memory")] -impl From for ZBytes { - fn from(t: ZShmMut) -> Self { - ZSerde.serialize(t) - } -} - -#[cfg(feature = "shared-memory")] -impl<'a> Deserialize<&'a zshm> for ZSerde { - type Input<'b> = &'a ZBytes; - type Error = ZDeserializeError; - - fn deserialize(self, v: Self::Input<'a>) -> Result<&'a zshm, Self::Error> { - // A ZShm is expected to have only one slice - let mut zslices = v.0.zslices(); - if let Some(zs) = zslices.next() { - if let Some(shmb) = zs.downcast_ref::() { - return Ok(shmb.into()); - } + impl<'a> Serialize<'a> for &ZShm { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } - Err(ZDeserializeError) - } -} - -#[cfg(feature = "shared-memory")] -impl<'a> TryFrom<&'a ZBytes> for &'a zshm { - type Error = ZDeserializeError; - - fn try_from(value: &'a ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -#[cfg(feature = "shared-memory")] -impl<'a> TryFrom<&'a mut ZBytes> for &'a mut zshm { - type Error = ZDeserializeError; - - fn try_from(value: &'a mut ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -#[cfg(feature = "shared-memory")] -impl<'a> Deserialize<&'a mut zshm> for ZSerde { - type Input<'b> = &'a mut ZBytes; - type Error = ZDeserializeError; - - fn deserialize(self, v: Self::Input<'a>) -> Result<&'a mut zshm, Self::Error> { - // A ZSliceShmBorrowMut is expected to have only one slice - let mut zslices = v.0.zslices_mut(); - if let Some(zs) = zslices.next() { - // SAFETY: ShmBufInner cannot change the size of the slice - if let Some(shmb) = unsafe { zs.downcast_mut::() } { - return Ok(shmb.into()); - } + fn serialize(self) -> Result, Self::Error> { + self.clone().serialize() } - Err(ZDeserializeError) } -} - -#[cfg(feature = "shared-memory")] -impl<'a> Deserialize<&'a mut zshmmut> for ZSerde { - type Input<'b> = &'a mut ZBytes; - type Error = ZDeserializeError; - - fn deserialize(self, v: Self::Input<'a>) -> Result<&'a mut zshmmut, Self::Error> { - // A ZSliceShmBorrowMut is expected to have only one slice - let mut zslices = v.0.zslices_mut(); - if let Some(zs) = zslices.next() { - // SAFETY: ShmBufInner cannot change the size of the slice - if let Some(shmb) = unsafe { zs.downcast_mut::() } { - return shmb.try_into().map_err(|_| ZDeserializeError); - } + impl From for ZBytes { + fn from(value: ZShm) -> Self { + ZBytes(value.into()) } - Err(ZDeserializeError) - } -} - -#[cfg(feature = "shared-memory")] -impl<'a> TryFrom<&'a mut ZBytes> for &'a mut zshmmut { - type Error = ZDeserializeError; - - fn try_from(value: &'a mut ZBytes) -> Result { - ZSerde.deserialize(value) } -} - -// Tuple (a, b) -macro_rules! impl_tuple2 { - ($t:expr) => {{ - let (a, b) = $t; - let codec = Zenoh080::new(); - let mut buffer: ZBuf = ZBuf::empty(); - let mut writer = buffer.writer(); - let apld: ZBytes = a.into(); - let bpld: ZBytes = b.into(); - - // SAFETY: we are serializing slices on a ZBuf, so serialization will never - // fail unless we run out of memory. In that case, Rust memory allocator - // will panic before the serializer has any chance to fail. - unsafe { - codec.write(&mut writer, &apld.0).unwrap_unchecked(); - codec.write(&mut writer, &bpld.0).unwrap_unchecked(); + impl SerializedSize for ZShmMut {} + impl<'a> Serialize<'a> for ZShmMut { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } - - ZBytes::new(buffer) - }}; -} - -impl Serialize<(A, B)> for ZSerde -where - A: Into, - B: Into, -{ - type Output = ZBytes; - - fn serialize(self, t: (A, B)) -> Self::Output { - impl_tuple2!(t) - } -} - -impl Serialize<&(A, B)> for ZSerde -where - for<'a> &'a A: Into, - for<'b> &'b B: Into, -{ - type Output = ZBytes; - - fn serialize(self, t: &(A, B)) -> Self::Output { - impl_tuple2!(t) - } -} - -impl From<(A, B)> for ZBytes -where - A: Into, - B: Into, -{ - fn from(value: (A, B)) -> Self { - ZSerde.serialize(value) - } -} - -#[derive(Debug)] -pub enum ZReadOrDeserializeErrorTuple2 -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, -{ - One(ZReadOrDeserializeError), - Two(ZReadOrDeserializeError), -} - -impl std::fmt::Display for ZReadOrDeserializeErrorTuple2 -where - A: Debug, - A: TryFrom, - >::Error: Debug, - B: Debug, - B: TryFrom, - >::Error: Debug, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ZReadOrDeserializeErrorTuple2::One(e) => { - f.write_fmt(format_args!("1st tuple element: {}", e)) - } - ZReadOrDeserializeErrorTuple2::Two(e) => { - f.write_fmt(format_args!("2nd tuple element: {}", e)) - } + fn serialize(self) -> Result, Self::Error> { + Ok(ZBytes::from(self).into()) } } -} - -impl std::error::Error for ZReadOrDeserializeErrorTuple2 -where - A: Debug, - A: TryFrom, - >::Error: Debug, - B: Debug, - B: TryFrom, - >::Error: Debug, -{ -} - -impl Deserialize<(A, B)> for ZSerde -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, -{ - type Input<'a> = &'a ZBytes; - type Error = ZReadOrDeserializeErrorTuple2; - - fn deserialize(self, bytes: Self::Input<'_>) -> Result<(A, B), Self::Error> { - let codec = Zenoh080::new(); - let mut reader = bytes.0.reader(); - - let abuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple2::One(ZReadOrDeserializeError::Read(ReadError)) - })?; - let apld = ZBytes::new(abuf); - let a = A::try_from(apld).map_err(|e| { - ZReadOrDeserializeErrorTuple2::One(ZReadOrDeserializeError::Deserialize(e)) - })?; - - let bbuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple2::Two(ZReadOrDeserializeError::Read(ReadError)) - })?; - let bpld = ZBytes::new(bbuf); - let b = B::try_from(bpld).map_err(|e| { - ZReadOrDeserializeErrorTuple2::Two(ZReadOrDeserializeError::Deserialize(e)) - })?; - - Ok((a, b)) - } -} - -impl TryFrom for (A, B) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for (A, B) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for (A, B) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// Tuple (a, b, c) -macro_rules! impl_tuple3 { - ($t:expr) => {{ - let (a, b, c) = $t; - - let codec = Zenoh080::new(); - let mut buffer: ZBuf = ZBuf::empty(); - let mut writer = buffer.writer(); - let apld: ZBytes = a.into(); - let bpld: ZBytes = b.into(); - let cpld: ZBytes = c.into(); - - // SAFETY: we are serializing slices on a ZBuf, so serialization will never - // fail unless we run out of memory. In that case, Rust memory allocator - // will panic before the serializer has any chance to fail. - unsafe { - codec.write(&mut writer, &apld.0).unwrap_unchecked(); - codec.write(&mut writer, &bpld.0).unwrap_unchecked(); - codec.write(&mut writer, &cpld.0).unwrap_unchecked(); + impl From for ZBytes { + fn from(value: ZShmMut) -> Self { + ZBytes(value.into()) } - - ZBytes::new(buffer) - }}; -} - -impl Serialize<(A, B, C)> for ZSerde -where - A: Into, - B: Into, - C: Into, -{ - type Output = ZBytes; - - fn serialize(self, t: (A, B, C)) -> Self::Output { - impl_tuple3!(t) - } -} - -impl Serialize<&(A, B, C)> for ZSerde -where - for<'a> &'a A: Into, - for<'b> &'b B: Into, - for<'b> &'b C: Into, -{ - type Output = ZBytes; - - fn serialize(self, t: &(A, B, C)) -> Self::Output { - impl_tuple3!(t) - } -} - -impl From<(A, B, C)> for ZBytes -where - A: Into, - B: Into, - C: Into, -{ - fn from(value: (A, B, C)) -> Self { - ZSerde.serialize(value) } -} - -#[derive(Debug)] -pub enum ZReadOrDeserializeErrorTuple3 -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, -{ - One(ZReadOrDeserializeError), - Two(ZReadOrDeserializeError), - Three(ZReadOrDeserializeError), -} -impl std::fmt::Display for ZReadOrDeserializeErrorTuple3 -where - A: Debug, - A: TryFrom, - >::Error: Debug, - B: Debug, - B: TryFrom, - >::Error: Debug, - C: Debug, - C: TryFrom, - >::Error: Debug, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ZReadOrDeserializeErrorTuple3::One(e) => { - f.write_fmt(format_args!("1st tuple element: {}", e)) - } - ZReadOrDeserializeErrorTuple3::Two(e) => { - f.write_fmt(format_args!("2nd tuple element: {}", e)) - } - ZReadOrDeserializeErrorTuple3::Three(e) => { - f.write_fmt(format_args!("3rd tuple element: {}", e)) - } + impl SerializedSize for &zshm {} + impl<'a> Serialize<'a> for &zshm { + type Error = Infallible; + fn write(self, _writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + unimplemented!() } - } -} - -impl std::error::Error for ZReadOrDeserializeErrorTuple3 -where - A: Debug, - A: TryFrom, - >::Error: Debug, - B: Debug, - B: TryFrom, - >::Error: Debug, - C: Debug, - C: TryFrom, - >::Error: Debug, -{ -} - -impl Deserialize<(A, B, C)> for ZSerde -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, -{ - type Input<'a> = &'a ZBytes; - type Error = ZReadOrDeserializeErrorTuple3; - - fn deserialize(self, bytes: Self::Input<'_>) -> Result<(A, B, C), Self::Error> { - let codec = Zenoh080::new(); - let mut reader = bytes.0.reader(); - - let abuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple3::One(ZReadOrDeserializeError::Read(ReadError)) - })?; - let apld = ZBytes::new(abuf); - let a = A::try_from(apld).map_err(|e| { - ZReadOrDeserializeErrorTuple3::One(ZReadOrDeserializeError::Deserialize(e)) - })?; - - let bbuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple3::Two(ZReadOrDeserializeError::Read(ReadError)) - })?; - let bpld = ZBytes::new(bbuf); - let b = B::try_from(bpld).map_err(|e| { - ZReadOrDeserializeErrorTuple3::Two(ZReadOrDeserializeError::Deserialize(e)) - })?; - - let cbuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple3::Three(ZReadOrDeserializeError::Read(ReadError)) - })?; - let cpld = ZBytes::new(cbuf); - let c = C::try_from(cpld).map_err(|e| { - ZReadOrDeserializeErrorTuple3::Three(ZReadOrDeserializeError::Deserialize(e)) - })?; - - Ok((a, b, c)) - } -} - -impl TryFrom for (A, B, C) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple3; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for (A, B, C) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple3; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for (A, B, C) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple3; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// Tuple (a, b, c, d) -macro_rules! impl_tuple4 { - ($t:expr) => {{ - let (a, b, c, d) = $t; - - let codec = Zenoh080::new(); - let mut buffer: ZBuf = ZBuf::empty(); - let mut writer = buffer.writer(); - let apld: ZBytes = a.into(); - let bpld: ZBytes = b.into(); - let cpld: ZBytes = c.into(); - let dpld: ZBytes = d.into(); - - // SAFETY: we are serializing slices on a ZBuf, so serialization will never - // fail unless we run out of memory. In that case, Rust memory allocator - // will panic before the serializer has any chance to fail. - unsafe { - codec.write(&mut writer, &apld.0).unwrap_unchecked(); - codec.write(&mut writer, &bpld.0).unwrap_unchecked(); - codec.write(&mut writer, &cpld.0).unwrap_unchecked(); - codec.write(&mut writer, &dpld.0).unwrap_unchecked(); + fn serialize(self) -> Result, Self::Error> { + Ok(ZBytes::from(self).into()) } - - ZBytes::new(buffer) - }}; -} - -impl Serialize<(A, B, C, D)> for ZSerde -where - A: Into, - B: Into, - C: Into, - D: Into, -{ - type Output = ZBytes; - - fn serialize(self, t: (A, B, C, D)) -> Self::Output { - impl_tuple4!(t) - } -} - -impl Serialize<&(A, B, C, D)> for ZSerde -where - for<'a> &'a A: Into, - for<'b> &'b B: Into, - for<'b> &'b C: Into, - for<'b> &'b D: Into, -{ - type Output = ZBytes; - - fn serialize(self, t: &(A, B, C, D)) -> Self::Output { - impl_tuple4!(t) } -} - -impl From<(A, B, C, D)> for ZBytes -where - A: Into, - B: Into, - C: Into, - D: Into, -{ - fn from(value: (A, B, C, D)) -> Self { - ZSerde.serialize(value) + impl From<&zshm> for ZBytes { + fn from(value: &zshm) -> Self { + value.to_owned().into() + } } } -#[derive(Debug)] -pub enum ZReadOrDeserializeErrorTuple4 -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, - D: TryFrom, - >::Error: Debug, -{ - One(ZReadOrDeserializeError), - Two(ZReadOrDeserializeError), - Three(ZReadOrDeserializeError), - Four(ZReadOrDeserializeError), -} - -impl std::fmt::Display for ZReadOrDeserializeErrorTuple4 -where - A: Debug, - A: TryFrom, - >::Error: Debug, - B: Debug, - B: TryFrom, - >::Error: Debug, - C: Debug, - C: TryFrom, - >::Error: Debug, - D: Debug, - D: TryFrom, - >::Error: Debug, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ZReadOrDeserializeErrorTuple4::One(e) => { - f.write_fmt(format_args!("1st tuple element: {}", e)) +macro_rules! impl_tuple { + ($($ty:ident/$i:tt),* $(,)?) => { + impl_tuple!(@;$($ty/$i),*); + }; + (@$($ty:ident/$i:tt),*; $next:ident/$next_i:tt $(, $remain:ident/$remain_i:tt)*) => { + impl_tuple!(@@$($ty/$i),*); + impl_tuple!(@$($ty/$i,)* $next/$next_i; $($remain/$remain_i),*); + }; + (@$($ty:ident/$i:tt),*;) => { + impl_tuple!(@@$($ty/$i),*); + }; + (@@$($ty:ident/$i:tt),* $(,)?) => { + impl<$($ty: SerializedSize),*> SerializedSize for ($($ty,)*) { + const FIXED_SIZE: Option = loop { + $(if $ty::FIXED_SIZE.is_none() { break None; })* + break Some(0 $(+ match $ty::FIXED_SIZE { Some(s) => s, None => unreachable!()})*) + }; + } + #[allow(unused)] + impl<'a, $($ty: Serialize<'a, Error=Infallible>),*> Serialize<'a> for ($($ty,)*) { + type Error = Infallible; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + $(self.$i.write(writer)?;)* + Ok(()) } - ZReadOrDeserializeErrorTuple4::Two(e) => { - f.write_fmt(format_args!("2nd tuple element: {}", e)) + fn serialize(self) -> Result, Self::Error> { + let mut zbytes = ZBytes::new(); + let mut writer = zbytes.writer(); + $(writer.serialize(self.$i);)* + Ok(zbytes.into()) } - ZReadOrDeserializeErrorTuple4::Three(e) => { - f.write_fmt(format_args!("3rd tuple element: {}", e)) + } + #[allow(unused)] + impl<'a, $($ty: SerializedSize),*> Serialize<'a> for &'a ($($ty,)*) where $(&'a $ty: Serialize<'a, Error=Infallible>),* { + type Error = Infallible; + fn write(self, writer: &mut ZBytesWriter) -> Result<(), Self::Error> { + $(self.$i.write(writer)?;)* + Ok(()) } - ZReadOrDeserializeErrorTuple4::Four(e) => { - f.write_fmt(format_args!("4th tuple element: {}", e)) + fn serialize(self) -> Result, Self::Error> { + let mut zbytes = ZBytes::new(); + let mut writer = zbytes.writer(); + $(writer.serialize(&self.$i);)* + Ok(zbytes.into()) } } - } -} - -impl std::error::Error for ZReadOrDeserializeErrorTuple4 -where - A: Debug, - A: TryFrom, - >::Error: Debug, - B: Debug, - B: TryFrom, - >::Error: Debug, - C: Debug, - C: TryFrom, - >::Error: Debug, - D: Debug, - D: TryFrom, - >::Error: Debug, -{ -} - -impl Deserialize<(A, B, C, D)> for ZSerde -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, - D: TryFrom, - >::Error: Debug, -{ - type Input<'a> = &'a ZBytes; - type Error = ZReadOrDeserializeErrorTuple4; - - fn deserialize(self, bytes: Self::Input<'_>) -> Result<(A, B, C, D), Self::Error> { - let codec = Zenoh080::new(); - let mut reader = bytes.0.reader(); - - let abuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple4::One(ZReadOrDeserializeError::Read(ReadError)) - })?; - let apld = ZBytes::new(abuf); - let a = A::try_from(apld).map_err(|e| { - ZReadOrDeserializeErrorTuple4::One(ZReadOrDeserializeError::Deserialize(e)) - })?; - - let bbuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple4::Two(ZReadOrDeserializeError::Read(ReadError)) - })?; - let bpld = ZBytes::new(bbuf); - let b = B::try_from(bpld).map_err(|e| { - ZReadOrDeserializeErrorTuple4::Two(ZReadOrDeserializeError::Deserialize(e)) - })?; - - let cbuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple4::Three(ZReadOrDeserializeError::Read(ReadError)) - })?; - let cpld = ZBytes::new(cbuf); - let c = C::try_from(cpld).map_err(|e| { - ZReadOrDeserializeErrorTuple4::Three(ZReadOrDeserializeError::Deserialize(e)) - })?; - - let dbuf: ZBuf = codec.read(&mut reader).map_err(|_| { - ZReadOrDeserializeErrorTuple4::Four(ZReadOrDeserializeError::Read(ReadError)) - })?; - let dpld = ZBytes::new(dbuf); - let d = D::try_from(dpld).map_err(|e| { - ZReadOrDeserializeErrorTuple4::Four(ZReadOrDeserializeError::Deserialize(e)) - })?; - - Ok((a, b, c, d)) - } -} - -impl TryFrom for (A, B, C, D) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, - D: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple4; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for (A, B, C, D) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, - D: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple4; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for (A, B, C, D) -where - A: TryFrom, - >::Error: Debug, - B: TryFrom, - >::Error: Debug, - C: TryFrom, - >::Error: Debug, - D: TryFrom, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple4; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } -} - -// HashMap -impl Serialize> for ZSerde -where - A: Into, - B: Into, -{ - type Output = ZBytes; - - fn serialize(self, mut t: HashMap) -> Self::Output { - ZBytes::from_iter(t.drain()) - } -} - -impl Serialize<&HashMap> for ZSerde -where - for<'a> &'a A: Into, - for<'b> &'b B: Into, -{ - type Output = ZBytes; - - fn serialize(self, t: &HashMap) -> Self::Output { - ZBytes::from_iter(t.iter()) - } -} - -impl From> for ZBytes -where - A: Into, - B: Into, -{ - fn from(value: HashMap) -> Self { - ZSerde.serialize(value) - } -} - -impl Deserialize> for ZSerde -where - A: TryFrom + Debug + std::cmp::Eq + std::hash::Hash, - >::Error: Debug, - B: TryFrom + Debug, - >::Error: Debug, -{ - type Input<'a> = &'a ZBytes; - type Error = ZReadOrDeserializeErrorTuple2; - - fn deserialize(self, bytes: Self::Input<'_>) -> Result, Self::Error> { - let mut hm = HashMap::new(); - for res in bytes.iter::<(A, B)>() { - let (k, v) = res?; - hm.insert(k, v); + #[allow(unused)] + impl<'a, $($ty: Deserialize<'a>),*> Deserialize<'a> for ($($ty,)*) { + fn read(reader: &mut ZBytesReader) -> Result { + Ok(($($ty::read(reader)?,)*)) + } + fn deserialize(zbytes: &'a ZBytes) -> Result { + let mut reader = zbytes.reader(); + Ok(($(reader.try_deserialize::<$ty>()?,)*)) + } + fn try_from_zbytes(zbytes: ZBytes) -> Result { + let mut reader = zbytes.reader(); + Ok(($(reader.try_deserialize::<$ty>()?,)*)) + } } - Ok(hm) - } -} - -impl TryFrom for HashMap -where - A: TryFrom + Debug + std::cmp::Eq + std::hash::Hash, - >::Error: Debug, - B: TryFrom + Debug, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: ZBytes) -> Result { - ZSerde.deserialize(&value) - } -} - -impl TryFrom<&ZBytes> for HashMap -where - A: TryFrom + Debug + std::cmp::Eq + std::hash::Hash, - >::Error: Debug, - B: TryFrom + Debug, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: &ZBytes) -> Result { - ZSerde.deserialize(value) - } -} - -impl TryFrom<&mut ZBytes> for HashMap -where - A: TryFrom + Debug + std::cmp::Eq + std::hash::Hash, - >::Error: Debug, - B: TryFrom + Debug, - >::Error: Debug, -{ - type Error = ZReadOrDeserializeErrorTuple2; - - fn try_from(value: &mut ZBytes) -> Result { - ZSerde.deserialize(&*value) - } + }; } - +impl_tuple!(T0 / 0, T1 / 1, T2 / 2,); +// T3 / 3, +// T4 / 4, +// T5 / 5, +// T6 / 6, +// T7 / 7, +// T8 / 8, +// T9 / 9, +// T10 / 10, +// T11 / 11, +// T12 / 12, +// T13 / 13, +// T14 / 14, +// T15 / 15 + +// TODO do we really need this? // Protocol attachment extension impl From for AttachmentType { fn from(this: ZBytes) -> Self { @@ -3398,7 +1584,7 @@ mod tests { println!("Serialize:\t{:?}", t); let v = ZBytes::serialize(t); println!("Deserialize:\t{:?}", v); - let o: $t = v.deserialize().unwrap(); + let o: $t = v.try_deserialize().unwrap(); assert_eq!(i, o); println!(""); }; @@ -3513,7 +1699,7 @@ mod tests { // WARN: test function body produces stack overflow, so I split it into subroutines #[inline(never)] fn reader_writer() { - let mut bytes = ZBytes::empty(); + let mut bytes = ZBytes::new(); let mut writer = bytes.writer(); let i1 = 1_u8; @@ -3623,7 +1809,7 @@ mod tests { println!("Serialize:\t{:?}", hm); let p = ZBytes::from(hm.clone()); println!("Deserialize:\t{:?}\n", p); - let o = p.deserialize::>().unwrap(); + let o = p.try_deserialize::>().unwrap(); assert_eq!(hm, o); let mut hm: HashMap> = HashMap::new(); @@ -3632,7 +1818,7 @@ mod tests { println!("Serialize:\t{:?}", hm); let p = ZBytes::from(hm.clone()); println!("Deserialize:\t{:?}\n", p); - let o = p.deserialize::>>().unwrap(); + let o = p.try_deserialize::>>().unwrap(); assert_eq!(hm, o); let mut hm: HashMap = HashMap::new(); @@ -3641,7 +1827,7 @@ mod tests { println!("Serialize:\t{:?}", hm); let p = ZBytes::from(hm.clone()); println!("Deserialize:\t{:?}\n", p); - let o = p.deserialize::>().unwrap(); + let o = p.try_deserialize::>().unwrap(); assert_eq!(hm, o); let mut hm: HashMap = HashMap::new(); @@ -3650,7 +1836,7 @@ mod tests { println!("Serialize:\t{:?}", hm); let p = ZBytes::from(hm.clone()); println!("Deserialize:\t{:?}\n", p); - let o = p.deserialize::>().unwrap(); + let o = p.try_deserialize::>().unwrap(); assert_eq!(hm, o); let mut hm: HashMap = HashMap::new(); @@ -3659,7 +1845,7 @@ mod tests { println!("Serialize:\t{:?}", hm); let p = ZBytes::from(hm.clone()); println!("Deserialize:\t{:?}\n", p); - let o = p.deserialize::>().unwrap(); + let o = p.try_deserialize::>().unwrap(); assert_eq!(hm, o); let mut hm: HashMap, Cow<'static, str>> = HashMap::new(); @@ -3668,7 +1854,7 @@ mod tests { println!("Serialize:\t{:?}", hm); let p = ZBytes::from(hm.clone()); println!("Deserialize:\t{:?}\n", p); - let o = p.deserialize::, Cow>>().unwrap(); + let o = p.try_deserialize::, Cow>>().unwrap(); assert_eq!(hm, o); } hashmap(); diff --git a/zenoh/src/api/encoding.rs b/zenoh/src/api/encoding.rs index bc335a5fc2..6bc9c4de77 100644 --- a/zenoh/src/api/encoding.rs +++ b/zenoh/src/api/encoding.rs @@ -966,14 +966,6 @@ impl EncodingMapping for serde_yaml::Value { const ENCODING: Encoding = Encoding::APPLICATION_YAML; } -impl EncodingMapping for serde_cbor::Value { - const ENCODING: Encoding = Encoding::APPLICATION_CBOR; -} - -impl EncodingMapping for serde_pickle::Value { - const ENCODING: Encoding = Encoding::APPLICATION_PYTHON_SERIALIZED_OBJECT; -} - impl Encoding { #[zenoh_macros::internal] pub fn id(&self) -> EncodingId { diff --git a/zenoh/src/api/publisher.rs b/zenoh/src/api/publisher.rs index efe74a9c1a..6380b614fe 100644 --- a/zenoh/src/api/publisher.rs +++ b/zenoh/src/api/publisher.rs @@ -13,7 +13,7 @@ // use std::{ - convert::TryFrom, + convert::{Infallible, TryFrom}, fmt, future::{IntoFuture, Ready}, pin::Pin, @@ -48,7 +48,10 @@ use super::{ sample::{Locality, Sample, SampleFields}, session::UndeclarableSealed, }; -use crate::api::{session::WeakSession, Id}; +use crate::{ + api::{session::WeakSession, Id}, + bytes::Serialize, +}; pub(crate) struct PublisherState { pub(crate) id: Id, @@ -179,14 +182,14 @@ impl<'a> Publisher<'a> { /// # } /// ``` #[inline] - pub fn put(&self, payload: IntoZBytes) -> PublisherPutBuilder<'_> + pub fn put<'p, IntoZBytes>(&self, payload: IntoZBytes) -> PublisherPutBuilder<'_> where - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { PublicationBuilder { publisher: self, kind: PublicationBuilderPut { - payload: payload.into(), + payload: ZBytes::serialize(payload), encoding: self.encoding.clone(), }, timestamp: None, @@ -909,7 +912,7 @@ mod tests { assert_eq!(sample.kind, kind); if let SampleKind::Put = kind { - assert_eq!(sample.payload.deserialize::().unwrap(), VALUE); + assert_eq!(sample.payload.try_deserialize::().unwrap(), VALUE); } } @@ -936,7 +939,7 @@ mod tests { assert_eq!(sample.kind, kind); if let SampleKind::Put = kind { - assert_eq!(sample.payload.deserialize::().unwrap(), VALUE); + assert_eq!(sample.payload.try_deserialize::().unwrap(), VALUE); } } diff --git a/zenoh/src/api/query.rs b/zenoh/src/api/query.rs index 8fc0ad1ec4..232ac0e19c 100644 --- a/zenoh/src/api/query.rs +++ b/zenoh/src/api/query.rs @@ -14,6 +14,7 @@ use std::{ collections::HashMap, + convert::Infallible, error::Error, fmt::Display, future::{IntoFuture, Ready}, @@ -47,7 +48,7 @@ use super::{ }; #[cfg(feature = "unstable")] use super::{sample::SourceInfo, selector::ZenohParameters}; -use crate::bytes::OptionZBytes; +use crate::bytes::{OptionZBytes, Serialize}; /// The replies consolidation strategy to apply on replies to a [`get`](Session::get). #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -382,12 +383,12 @@ impl<'a, 'b> SessionGetBuilder<'a, 'b, DefaultHandler> { } impl<'a, 'b, Handler> SessionGetBuilder<'a, 'b, Handler> { #[inline] - pub fn payload(mut self, payload: IntoZBytes) -> Self + pub fn payload<'p, IntoZBytes>(mut self, payload: IntoZBytes) -> Self where - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { let mut value = self.value.unwrap_or_default(); - value.payload = payload.into(); + value.payload = ZBytes::serialize(payload); self.value = Some(value); self } diff --git a/zenoh/src/api/queryable.rs b/zenoh/src/api/queryable.rs index 56dbec7e19..57ced487ce 100644 --- a/zenoh/src/api/queryable.rs +++ b/zenoh/src/api/queryable.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use std::{ + convert::Infallible, fmt, future::{IntoFuture, Ready}, ops::{Deref, DerefMut}, @@ -53,6 +54,7 @@ use crate::{ value::Value, Id, }, + bytes::Serialize, handlers::Callback, net::primitives::Primitives, Session, @@ -153,7 +155,7 @@ impl Query { /// Unless the query has enabled disjoint replies (you can check this through [`Query::accepts_replies`]), /// replying on a disjoint key expression will result in an error when resolving the reply. #[inline(always)] - pub fn reply<'b, TryIntoKeyExpr, IntoZBytes>( + pub fn reply<'p, 'b, TryIntoKeyExpr, IntoZBytes>( &self, key_expr: TryIntoKeyExpr, payload: IntoZBytes, @@ -161,14 +163,14 @@ impl Query { where TryIntoKeyExpr: TryInto>, >>::Error: Into, - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { ReplyBuilder { query: self, key_expr: key_expr.try_into().map_err(Into::into), qos: response::ext::QoSType::RESPONSE.into(), kind: ReplyBuilderPut { - payload: payload.into(), + payload: ZBytes::serialize(payload), encoding: Encoding::default(), }, timestamp: None, @@ -180,9 +182,9 @@ impl Query { /// Sends a [`crate::query::ReplyError`] as a reply to this Query. #[inline(always)] - pub fn reply_err(&self, payload: IntoZBytes) -> ReplyErrBuilder<'_> + pub fn reply_err<'p, IntoZBytes>(&self, payload: IntoZBytes) -> ReplyErrBuilder<'_> where - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { ReplyErrBuilder { query: self, diff --git a/zenoh/src/api/sample.rs b/zenoh/src/api/sample.rs index 20ccdf6617..c609461343 100644 --- a/zenoh/src/api/sample.rs +++ b/zenoh/src/api/sample.rs @@ -13,9 +13,11 @@ // //! Sample primitives -use std::{convert::TryFrom, fmt}; +use std::{ + convert::{Infallible, TryFrom}, + fmt, +}; -use serde::{Deserialize, Serialize}; use zenoh_config::wrappers::EntityGlobalId; #[cfg(feature = "unstable")] use zenoh_protocol::core::Reliability; @@ -28,13 +30,14 @@ use super::{ builders::sample::QoSBuilderTrait, bytes::ZBytes, encoding::Encoding, key_expr::KeyExpr, publisher::Priority, value::Value, }; +use crate::bytes::Serialize; /// The sequence number of the [`Sample`] from the source. pub type SourceSn = u32; /// The locality of samples to be received by subscribers or targeted by publishers. #[zenoh_macros::unstable] -#[derive(Clone, Copy, Debug, Default, Serialize, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Default, serde::Serialize, PartialEq, Eq)] pub enum Locality { SessionLocal, Remote, @@ -61,7 +64,7 @@ pub(crate) struct DataInfo { } pub(crate) trait DataInfoIntoSample { - fn into_sample( + fn into_sample<'p, IntoKeyExpr, IntoZBytes>( self, key_expr: IntoKeyExpr, payload: IntoZBytes, @@ -70,7 +73,7 @@ pub(crate) trait DataInfoIntoSample { ) -> Sample where IntoKeyExpr: Into>, - IntoZBytes: Into; + IntoZBytes: Serialize<'p, Error = Infallible>; } impl DataInfoIntoSample for DataInfo { @@ -79,7 +82,7 @@ impl DataInfoIntoSample for DataInfo { // The test for it is intentionally not added to avoid inserting extra "if" into hot path. // The correctness of the data should be ensured by the caller. #[inline] - fn into_sample( + fn into_sample<'p, IntoKeyExpr, IntoZBytes>( self, key_expr: IntoKeyExpr, payload: IntoZBytes, @@ -88,11 +91,11 @@ impl DataInfoIntoSample for DataInfo { ) -> Sample where IntoKeyExpr: Into>, - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { Sample { key_expr: key_expr.into(), - payload: payload.into(), + payload: ZBytes::serialize(payload), kind: self.kind, encoding: self.encoding.unwrap_or_default(), timestamp: self.timestamp, @@ -111,7 +114,7 @@ impl DataInfoIntoSample for DataInfo { impl DataInfoIntoSample for Option { #[inline] - fn into_sample( + fn into_sample<'p, IntoKeyExpr, IntoZBytes>( self, key_expr: IntoKeyExpr, payload: IntoZBytes, @@ -120,7 +123,7 @@ impl DataInfoIntoSample for Option { ) -> Sample where IntoKeyExpr: Into>, - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { if let Some(data_info) = self { data_info.into_sample( @@ -133,7 +136,7 @@ impl DataInfoIntoSample for Option { } else { Sample { key_expr: key_expr.into(), - payload: payload.into(), + payload: ZBytes::serialize(payload), kind: SampleKind::Put, encoding: Encoding::default(), timestamp: None, @@ -250,7 +253,7 @@ impl Default for SourceInfo { /// The kind of a `Sample`. #[repr(u8)] -#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)] pub enum SampleKind { /// if the `Sample` was issued by a `put` operation. #[default] diff --git a/zenoh/src/api/session.rs b/zenoh/src/api/session.rs index d39b7de055..3584dd1803 100644 --- a/zenoh/src/api/session.rs +++ b/zenoh/src/api/session.rs @@ -15,7 +15,7 @@ use std::collections::hash_map::Entry; use std::{ collections::HashMap, - convert::TryInto, + convert::{Infallible, TryInto}, fmt, future::{IntoFuture, Ready}, ops::Deref, @@ -101,6 +101,7 @@ use super::{ #[cfg(feature = "unstable")] use crate::api::selector::ZenohParameters; use crate::{ + bytes::Serialize, net::{ primitives::Primitives, routing::dispatcher::face::Face, @@ -919,7 +920,7 @@ impl Session { /// # } /// ``` #[inline] - pub fn put<'a, 'b: 'a, TryIntoKeyExpr, IntoZBytes>( + pub fn put<'p, 'a, 'b: 'a, TryIntoKeyExpr, IntoZBytes>( &'a self, key_expr: TryIntoKeyExpr, payload: IntoZBytes, @@ -927,12 +928,12 @@ impl Session { where TryIntoKeyExpr: TryInto>, >>::Error: Into, - IntoZBytes: Into, + IntoZBytes: Serialize<'p, Error = Infallible>, { SessionPutBuilder { publisher: self.declare_publisher(key_expr), kind: PublicationBuilderPut { - payload: payload.into(), + payload: ZBytes::serialize(payload), encoding: Encoding::default(), }, timestamp: None, @@ -1613,7 +1614,7 @@ impl SessionInner { for token in known_tokens { callback.call(Sample { key_expr: token, - payload: ZBytes::empty(), + payload: ZBytes::new(), kind: SampleKind::Put, encoding: Encoding::default(), timestamp: None, @@ -2360,7 +2361,7 @@ impl Primitives for WeakSession { let reply = Reply { result: Ok(Sample { key_expr, - payload: ZBytes::empty(), + payload: ZBytes::new(), kind: SampleKind::Put, encoding: Encoding::default(), timestamp: None, diff --git a/zenoh/src/api/value.rs b/zenoh/src/api/value.rs index 88470b3360..c209ac71d1 100644 --- a/zenoh/src/api/value.rs +++ b/zenoh/src/api/value.rs @@ -13,7 +13,11 @@ // //! Value primitives. + +use std::convert::Infallible; + use super::{bytes::ZBytes, encoding::Encoding}; +use crate::bytes::Serialize; /// A zenoh [`Value`] contains a `payload` and an [`Encoding`] that indicates how the payload's [`ZBytes`] should be interpreted. #[non_exhaustive] @@ -25,20 +29,20 @@ pub struct Value { impl Value { /// Creates a new [`Value`] with specified [`ZBytes`] and [`Encoding`]. - pub fn new(payload: T, encoding: E) -> Self + pub fn new<'a, T, E>(payload: T, encoding: E) -> Self where - T: Into, + T: Serialize<'a, Error = Infallible>, E: Into, { Value { - payload: payload.into(), + payload: ZBytes::serialize(payload), encoding: encoding.into(), } } /// Creates an empty [`Value`]. pub const fn empty() -> Self { Value { - payload: ZBytes::empty(), + payload: ZBytes::new(), encoding: Encoding::default(), } } diff --git a/zenoh/src/lib.rs b/zenoh/src/lib.rs index be8be3b024..52de017bd4 100644 --- a/zenoh/src/lib.rs +++ b/zenoh/src/lib.rs @@ -216,7 +216,7 @@ pub mod bytes { pub use crate::api::{ bytes::{ Deserialize, OptionZBytes, Serialize, ZBytes, ZBytesIterator, ZBytesReader, - ZBytesSliceIterator, ZBytesWriter, ZDeserializeError, ZSerde, + ZBytesSliceIterator, ZBytesWriter, ZDeserializeError, }, encoding::Encoding, }; diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 657bf8bf05..7a14f43555 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -616,7 +616,7 @@ fn local_data(context: &AdminContext, query: Query) { } tracing::trace!("AdminSpace router_data: {:?}", json); - let payload = match ZBytes::try_from(json) { + let payload = match ZBytes::try_serialize(json) { Ok(p) => p, Err(e) => { tracing::error!("Error serializing AdminSpace reply: {:?}", e); @@ -716,8 +716,9 @@ fn subscribers_data(context: &AdminContext, query: Query) { )) .unwrap(); if query.key_expr().intersects(&key) { - let payload = - ZBytes::from(serde_json::to_string(&sub.1).unwrap_or_else(|_| "{}".to_string())); + let payload = ZBytes::serialize( + serde_json::to_string(&sub.1).unwrap_or_else(|_| "{}".to_string()), + ); if let Err(e) = query .reply(key, payload) .encoding(Encoding::APPLICATION_JSON) @@ -740,8 +741,9 @@ fn queryables_data(context: &AdminContext, query: Query) { )) .unwrap(); if query.key_expr().intersects(&key) { - let payload = - ZBytes::from(serde_json::to_string(&qabl.1).unwrap_or_else(|_| "{}".to_string())); + let payload = ZBytes::serialize( + serde_json::to_string(&qabl.1).unwrap_or_else(|_| "{}".to_string()), + ); if let Err(e) = query .reply(key, payload) .encoding(Encoding::APPLICATION_JSON) @@ -768,10 +770,10 @@ fn plugins_data(context: &AdminContext, query: Query) { tracing::debug!("plugin status: {:?}", status); let key = root_key.join(status.id()).unwrap(); let status = serde_json::to_value(status).unwrap(); - match ZBytes::try_from(status) { - Ok(zbuf) => { + match ZBytes::try_serialize(status) { + Ok(zbytes) => { if let Err(e) = query - .reply(key, zbuf) + .reply(key, zbytes) .encoding(Encoding::APPLICATION_JSON) .wait() { @@ -825,12 +827,12 @@ fn plugins_status(context: &AdminContext, query: Query) { Ok(Ok(responses)) => { for response in responses { if let Ok(key_expr) = KeyExpr::try_from(response.key) { - match ZBytes::try_from(response.value) { - Ok(zbuf) => { - if let Err(e) = query.reply(key_expr, zbuf).encoding(Encoding::APPLICATION_JSON).wait() { + match ZBytes::try_serialize(response.value) { + Ok(zbytes) => { + if let Err(e) = query.reply(key_expr, zbytes).encoding(Encoding::APPLICATION_JSON).wait() { tracing::error!("Error sending AdminSpace reply: {:?}", e); } - }, + } Err(e) => tracing::debug!("Admin query error: {}", e), } } else { diff --git a/zenoh/tests/acl.rs b/zenoh/tests/acl.rs index 389abfa47a..1c0688b567 100644 --- a/zenoh/tests/acl.rs +++ b/zenoh/tests/acl.rs @@ -141,7 +141,7 @@ mod test { .callback(move |sample| { if sample.kind() == SampleKind::Put { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); } else if sample.kind() == SampleKind::Delete { let mut deleted = zlock!(deleted_clone); *deleted = true; @@ -195,7 +195,7 @@ mod test { .callback(move |sample| { if sample.kind() == SampleKind::Put { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); } else if sample.kind() == SampleKind::Delete { let mut deleted = zlock!(deleted_clone); *deleted = true; @@ -277,7 +277,7 @@ mod test { .callback(move |sample| { if sample.kind() == SampleKind::Put { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); } else if sample.kind() == SampleKind::Delete { let mut deleted = zlock!(deleted_clone); *deleted = true; @@ -358,7 +358,7 @@ mod test { .callback(move |sample| { if sample.kind() == SampleKind::Put { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); } else if sample.kind() == SampleKind::Delete { let mut deleted = zlock!(deleted_clone); *deleted = true; @@ -436,7 +436,7 @@ mod test { while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!("Error : {:?}", e), @@ -490,7 +490,7 @@ mod test { while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!("Error : {:?}", e), @@ -571,7 +571,7 @@ mod test { while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!("Error : {:?}", e), @@ -650,7 +650,7 @@ mod test { while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!("Error : {:?}", e), @@ -718,7 +718,7 @@ mod test { while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!("Error : {:?}", e), @@ -792,7 +792,7 @@ mod test { while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!("Error : {:?}", e), diff --git a/zenoh/tests/attachments.rs b/zenoh/tests/attachments.rs index dd9e287428..b483433f3a 100644 --- a/zenoh/tests/attachments.rs +++ b/zenoh/tests/attachments.rs @@ -20,7 +20,7 @@ fn attachment_pubsub() { let _sub = zenoh .declare_subscriber("test/attachment") .callback(|sample| { - println!("{}", sample.payload().deserialize::().unwrap()); + println!("{}", sample.payload().try_deserialize::().unwrap()); for (k, v) in sample .attachment() .unwrap() @@ -67,7 +67,7 @@ fn attachment_queries() { .callback(|query| { let s = query .payload() - .map(|p| p.deserialize::().unwrap()) + .map(|p| p.try_deserialize::().unwrap()) .unwrap_or_default(); println!("Query value: {}", s); diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index a49261c9d1..50c6b9afc4 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -901,7 +901,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); }) .await .unwrap(); @@ -969,7 +969,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); })) .unwrap(); @@ -1052,13 +1052,13 @@ client2name:client2passwd"; while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!( "Error : {}", e.payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ), } @@ -1137,13 +1137,13 @@ client2name:client2passwd"; while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!( "Error : {}", e.payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ), } @@ -1211,7 +1211,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); }) .await .unwrap(); @@ -1281,7 +1281,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); })) .unwrap(); @@ -1365,13 +1365,13 @@ client2name:client2passwd"; while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!( "Error : {}", e.payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ), } @@ -1451,13 +1451,13 @@ client2name:client2passwd"; while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!( "Error : {}", e.payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ), } @@ -1526,7 +1526,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); }) .await .unwrap(); @@ -1596,7 +1596,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); })) .unwrap(); @@ -1680,13 +1680,13 @@ client2name:client2passwd"; while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!( "Error : {}", e.payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ), } @@ -1766,13 +1766,13 @@ client2name:client2passwd"; while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { match reply.result() { Ok(sample) => { - received_value = sample.payload().deserialize::().unwrap(); + received_value = sample.payload().try_deserialize::().unwrap(); break; } Err(e) => println!( "Error : {}", e.payload() - .deserialize::() + .try_deserialize::() .unwrap_or_else(|e| format!("{}", e)) ), } @@ -1843,7 +1843,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); })) .unwrap(); @@ -1866,7 +1866,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); })) .unwrap(); @@ -1939,7 +1939,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); })) .unwrap(); @@ -1962,7 +1962,7 @@ client2name:client2passwd"; .declare_subscriber(KEY_EXPR) .callback(move |sample| { let mut temp_value = zlock!(temp_recv_value); - *temp_value = sample.payload().deserialize::().unwrap(); + *temp_value = sample.payload().try_deserialize::().unwrap(); })) .unwrap(); diff --git a/zenoh/tests/bytes.rs b/zenoh/tests/bytes.rs index c9a2e016f4..d46ef05967 100644 --- a/zenoh/tests/bytes.rs +++ b/zenoh/tests/bytes.rs @@ -53,7 +53,7 @@ fn shm_bytes_single_buf() { // branch to illustrate immutable access to SHM data { // deserialize ZBytes as an immutably borrowed zshm (ZBytes -> &zshm) - let borrowed_shm_buf: &zshm = payload.deserialize().unwrap(); + let borrowed_shm_buf: &zshm = payload.try_deserialize().unwrap(); // construct owned buffer from borrowed type (&zshm -> ZShm) let owned = borrowed_shm_buf.to_owned(); diff --git a/zenoh/tests/handler.rs b/zenoh/tests/handler.rs index d87917a0dd..46d11481eb 100644 --- a/zenoh/tests/handler.rs +++ b/zenoh/tests/handler.rs @@ -35,7 +35,7 @@ fn pubsub_with_ringbuffer() { sub.recv() .unwrap() .payload() - .deserialize::() + .try_deserialize::() .unwrap(), format!("put{i}") ); @@ -67,7 +67,11 @@ fn query_with_ringbuffer() { let query = queryable.recv().unwrap(); // Only receive the latest query assert_eq!( - query.payload().unwrap().deserialize::().unwrap(), + query + .payload() + .unwrap() + .try_deserialize::() + .unwrap(), "query2" ); } diff --git a/zenoh/tests/shm.rs b/zenoh/tests/shm.rs index 908fc5f2da..4650c7bac6 100644 --- a/zenoh/tests/shm.rs +++ b/zenoh/tests/shm.rs @@ -122,7 +122,7 @@ async fn test_session_pubsub(peer01: &Session, peer02: &Session, reliability: Re .declare_subscriber(&key_expr) .callback(move |sample| { assert_eq!(sample.payload().len(), size); - let _ = sample.payload().deserialize::<&zshm>().unwrap(); + let _ = sample.payload().try_deserialize::<&zshm>().unwrap(); c_msgs.fetch_add(1, Ordering::Relaxed); })) .unwrap();