From c76c856c38891b0b3a1ed079c34089708670bd91 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 12 Jun 2025 13:58:09 -0400 Subject: [PATCH 01/42] looking through noellas work --- src/lib.rs | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 204 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e7dfc60..a35746a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,39 +1,232 @@ use async_trait::async_trait; use std::sync::Arc; -use up_rust::{UListener, UMessage, UStatus, UTransport, UUri}; +use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode, UAttributes}; +use iceoryx2::prelude::*; +use protobuf::MessageField; + +mod custom_header; +mod transmission_data; +pub use custom_header::CustomHeader; +pub use transmission_data::TransmissionData; /// This will be the main struct for our uProtocol transport. /// It will hold the state necessary to communicate with iceoryx2, /// such as the service connection and active listeners. -pub struct Iceoryx2Transport {} + + +// Channel-based solution - iceoryx2 types are not Send/Sync, so we use channels +use std::thread; + +#[derive(Debug)] +enum TransportCommand { + Send { + message: UMessage, + response: std::sync::mpsc::Sender> + }, + RegisterListener { + source_filter: UUri, + sink_filter: Option, + // Remove Debug requirement by not deriving Debug or handling it manually + response: std::sync::mpsc::Sender>, + }, + UnregisterListener { + source_filter: UUri, + sink_filter: Option, + response: std::sync::mpsc::Sender>, + }, +} + +pub struct Iceoryx2Transport { + command_sender: std::sync::mpsc::Sender, +} + +impl Iceoryx2Transport { + pub fn new() -> Result { + let (tx, rx) = std::sync::mpsc::channel(); + + // Spawn background thread to handle iceoryx2 operations + thread::spawn(move || { + Self::background_task(rx); + }); + + Ok(Self { + command_sender: tx, + }) + } + + fn background_task(rx: std::sync::mpsc::Receiver) { + // Create iceoryx2 components in the background thread (single-threaded) + let node_result = NodeBuilder::new().create::(); + let node = match node_result { + Ok(node) => node, + Err(e) => { + eprintln!("Failed to create iceoryx2 node: {}", e); + return; + } + }; + + let service_result = node + .service_builder(&"My/Funk/ServiceName".try_into().unwrap()) + .publish_subscribe::() + .user_header::() + .open_or_create(); + + let service = match service_result { + Ok(service) => service, + Err(e) => { + eprintln!("Failed to create iceoryx2 service: {}", e); + return; + } + }; + + let publisher_result = service.publisher_builder().create(); + let publisher = match publisher_result { + Ok(publisher) => publisher, + Err(e) => { + eprintln!("Failed to create iceoryx2 publisher: {}", e); + return; + } + }; + + // Process commands + while let Ok(command) = rx.recv() { + match command { + TransportCommand::Send { message, response } => { + let result = Self::handle_send(&publisher, message); + let _ = response.send(result); + } + TransportCommand::RegisterListener { response, .. } => { + // TODO: Implement listener registration + let _ = response.send(Ok(())); + } + TransportCommand::UnregisterListener { response, .. } => { + // TODO: Implement listener unregistration + let _ = response.send(Ok(())); + } + } + } + } + + fn handle_send( + publisher: &iceoryx2::port::publisher::Publisher, + message: UMessage + ) -> Result<(), UStatus> { + // Convert UMessage to TransmissionData + let transmission_data = match TransmissionData::from_message(&message) { + Ok(data) => data, + Err(e) => return Err(e), + }; + + // Create custom header from UMessage attributes + let header = match CustomHeader::from_message(&message) { + Ok(header) => header, + Err(e) => return Err(e), + }; + + // Send the message + let sample = publisher.loan_uninit() + .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")))?; + + let sample_final = sample + .write_payload(transmission_data); + + sample_final.send() + .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to send: {e}")))?; + + Ok(()) + } +} // The #[async_trait] attribute enables async functions in our trait impl. #[async_trait] impl UTransport for Iceoryx2Transport { - async fn send(&self, _message: UMessage) -> Result<(), UStatus> { - todo!(); + async fn send(&self, message: UMessage) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::Send { + message, + response: tx, + }; + + self.command_sender.send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv() + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? } async fn register_listener( &self, - _source_filter: &UUri, - _sink_filter: Option<&UUri>, + source_filter: &UUri, + sink_filter: Option<&UUri>, _listener: Arc, ) -> Result<(), UStatus> { - todo!() + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::RegisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + response: tx, + }; + + self.command_sender.send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv() + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? } async fn unregister_listener( &self, - _source_filter: &UUri, - _sink_filter: Option<&UUri>, + source_filter: &UUri, + sink_filter: Option<&UUri>, _listener: Arc, ) -> Result<(), UStatus> { - todo!() + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::UnregisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + response: tx, + }; + + self.command_sender.send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv() + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? } } #[cfg(test)] mod tests { use super::*; -} + + #[tokio::test] + async fn test_transport_creation() { + // Test that we can create the transport without compilation errors + // Note: This might fail at runtime if iceoryx2 daemon isn't running + match Iceoryx2Transport::new() { + Ok(_transport) => println!("Transport created successfully"), + Err(e) => println!("Transport creation failed (expected if daemon not running): {:?}", e), + } + } + + #[tokio::test] + async fn test_send_message() { + if let Ok(transport) = Iceoryx2Transport::new() { + // Create a dummy UMessage + let message = UMessage { + attributes: MessageField::some(UAttributes::from(&uprotocol_header)), + payload: Some(vec![1, 2, 3, 4].into()), + ..Default::default() + }; + + // This will fail without iceoryx2 daemon, but should compile + match transport.send(message).await { + Ok(_) => println!("Message sent successfully"), + Err(e) => println!("Send failed (expected without daemon): {:?}", e), + } + } + } +} \ No newline at end of file From aec4d04966980613c395a88436832e11ea98e3c8 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 12 Jun 2025 14:17:07 -0400 Subject: [PATCH 02/42] more of what noella has done --- src/custom_header.rs | 45 +++++++++++++++++++++++++++++ src/transmission_data.rs | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 src/custom_header.rs create mode 100644 src/transmission_data.rs diff --git a/src/custom_header.rs b/src/custom_header.rs new file mode 100644 index 0000000..fe99763 --- /dev/null +++ b/src/custom_header.rs @@ -0,0 +1,45 @@ +// Copyright (c) 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use iceoryx2::prelude::*; +use up_rust::{UMessage, UStatus, UCode}; + +#[derive(Default, Debug, ZeroCopySend)] +// optional type name; if not set, `core::any::type_name::()` is used +#[type_name("CustomHeader")] +#[repr(C)] +pub struct CustomHeader { + pub version: i32, + pub timestamp: u64, +} + +impl CustomHeader { + pub fn from_user_header(header: &Self) -> Result { + Ok(Self { + version: header.version, + timestamp: header.timestamp, + }) + } +} + + +// In custom_header.rs, add: +impl CustomHeader { + pub fn from_message(message: &UMessage) -> Result { + // Extract header information from UMessage + Ok(Self { + // Set fields based on message.attributes + // This is just a placeholder - implement based on your needs + ..Default::default() + }) + } +} \ No newline at end of file diff --git a/src/transmission_data.rs b/src/transmission_data.rs new file mode 100644 index 0000000..9faf8a2 --- /dev/null +++ b/src/transmission_data.rs @@ -0,0 +1,62 @@ +// Copyright (c) 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use iceoryx2::prelude::*; +use up_rust::{UMessage, UStatus, UCode}; +use bytes::Bytes; + +#[derive(Debug, Clone, Copy, ZeroCopySend, Default)] +// optional type name; if not set, `core::any::type_name::()` is used +#[type_name("TransmissionData")] +#[repr(C)] +pub struct TransmissionData { + pub x: i32, + pub y: i32, + pub funky: f64, +} + +impl TransmissionData { + pub fn from_bytes(bytes: Vec) -> Result { + if bytes.len() != std::mem::size_of::() { + return Err(UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + "Invalid byte length for TransmissionData", + )); + } + + let mut data = Self { + x: 0, + y: 0, + funky: 0.0, + }; + let ptr = &mut data as *mut Self as *mut u8; + unsafe { + std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, bytes.len()); + } + Ok(data) + } + + + pub fn to_bytes(&self) -> Vec { + let mut bytes = vec![0u8; std::mem::size_of::()]; + let ptr = self as *const Self as *const u8; + unsafe { + std::ptr::copy_nonoverlapping(ptr, bytes.as_mut_ptr(), bytes.len()); + } + bytes + } + + pub fn from_message(message: &UMessage) -> Result { + let payload = message.payload.clone().unwrap_or_default(); + Self::from_bytes(payload.to_vec()) + } +} \ No newline at end of file From 3ec7d9378ddc0fad448c4424e76eb774f83d0b5d Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 12 Jun 2025 14:38:56 -0400 Subject: [PATCH 03/42] fixed all the errors reguarding the cargo test --- Cargo.lock | 121 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 ++ src/custom_header.rs | 47 ++++++++--------- src/lib.rs | 52 ++++++------------- 4 files changed, 161 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d7d142..e96ac67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,12 @@ dependencies = [ "syn", ] +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + [[package]] name = "backtrace" version = "0.3.75" @@ -491,6 +497,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.27" @@ -524,6 +540,17 @@ dependencies = [ "adler2", ] +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + [[package]] name = "nom" version = "7.1.3" @@ -555,6 +582,29 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -743,6 +793,15 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "redox_syscall" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.11.1" @@ -810,6 +869,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.219" @@ -851,6 +916,31 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "syn" version = "2.0.101" @@ -918,7 +1008,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1013,7 +1122,10 @@ name = "up-transport-iceoryx2-rust" version = "0.1.0" dependencies = [ "async-trait", + "bytes", "iceoryx2", + "protobuf", + "tokio", "up-rust", ] @@ -1101,6 +1213,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" diff --git a/Cargo.toml b/Cargo.toml index 942eae5..e61bce6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,6 @@ edition = "2024" up-rust = "0.5" iceoryx2 = "0.6.1" async-trait = "0.1" +protobuf = "3.7.2" +bytes = "1.10.1" +tokio = { version = "1", features = ["full"] } diff --git a/src/custom_header.rs b/src/custom_header.rs index fe99763..67cd948 100644 --- a/src/custom_header.rs +++ b/src/custom_header.rs @@ -1,20 +1,7 @@ -// Copyright (c) 2024 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache Software License 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license -// which is available at https://opensource.org/licenses/MIT. -// -// SPDX-License-Identifier: Apache-2.0 OR MIT - use iceoryx2::prelude::*; -use up_rust::{UMessage, UStatus, UCode}; +use up_rust::{UMessage, UStatus, UCode, UAttributes}; #[derive(Default, Debug, ZeroCopySend)] -// optional type name; if not set, `core::any::type_name::()` is used #[type_name("CustomHeader")] #[repr(C)] pub struct CustomHeader { @@ -29,17 +16,27 @@ impl CustomHeader { timestamp: header.timestamp, }) } + + pub fn from_message(_message: &UMessage) -> Result { + // For now, just default + Ok(Self::default()) + } } - -// In custom_header.rs, add: -impl CustomHeader { - pub fn from_message(message: &UMessage) -> Result { - // Extract header information from UMessage - Ok(Self { - // Set fields based on message.attributes - // This is just a placeholder - implement based on your needs - ..Default::default() - }) +// Assuming UAttributes has a field called `fields` which is Vec<(String, String)> +// Adjust if your actual UAttributes is different +impl From<&CustomHeader> for UAttributes { + fn from(header: &CustomHeader) -> UAttributes { + let mut attrs = UAttributes::default(); + + // Hypothetical code: add key-value pairs to attrs + // Replace this with your real API to insert attributes + // For example, if UAttributes has a `fields` Vec<(String, String)>: + // attrs.fields.push(("version".to_string(), header.version.to_string())); + // attrs.fields.push(("timestamp".to_string(), header.timestamp.to_string())); + + // If no such field exists, just return default or implement accordingly + + attrs } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index a35746a..e924de3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,12 +9,6 @@ mod transmission_data; pub use custom_header::CustomHeader; pub use transmission_data::TransmissionData; -/// This will be the main struct for our uProtocol transport. -/// It will hold the state necessary to communicate with iceoryx2, -/// such as the service connection and active listeners. - - -// Channel-based solution - iceoryx2 types are not Send/Sync, so we use channels use std::thread; #[derive(Debug)] @@ -26,7 +20,6 @@ enum TransportCommand { RegisterListener { source_filter: UUri, sink_filter: Option, - // Remove Debug requirement by not deriving Debug or handling it manually response: std::sync::mpsc::Sender>, }, UnregisterListener { @@ -44,7 +37,6 @@ impl Iceoryx2Transport { pub fn new() -> Result { let (tx, rx) = std::sync::mpsc::channel(); - // Spawn background thread to handle iceoryx2 operations thread::spawn(move || { Self::background_task(rx); }); @@ -55,9 +47,7 @@ impl Iceoryx2Transport { } fn background_task(rx: std::sync::mpsc::Receiver) { - // Create iceoryx2 components in the background thread (single-threaded) - let node_result = NodeBuilder::new().create::(); - let node = match node_result { + let node = match NodeBuilder::new().create::() { Ok(node) => node, Err(e) => { eprintln!("Failed to create iceoryx2 node: {}", e); @@ -65,13 +55,12 @@ impl Iceoryx2Transport { } }; - let service_result = node + let service = match node .service_builder(&"My/Funk/ServiceName".try_into().unwrap()) .publish_subscribe::() .user_header::() - .open_or_create(); - - let service = match service_result { + .open_or_create() + { Ok(service) => service, Err(e) => { eprintln!("Failed to create iceoryx2 service: {}", e); @@ -79,8 +68,7 @@ impl Iceoryx2Transport { } }; - let publisher_result = service.publisher_builder().create(); - let publisher = match publisher_result { + let publisher = match service.publisher_builder().create() { Ok(publisher) => publisher, Err(e) => { eprintln!("Failed to create iceoryx2 publisher: {}", e); @@ -88,7 +76,6 @@ impl Iceoryx2Transport { } }; - // Process commands while let Ok(command) = rx.recv() { match command { TransportCommand::Send { message, response } => { @@ -111,24 +98,15 @@ impl Iceoryx2Transport { publisher: &iceoryx2::port::publisher::Publisher, message: UMessage ) -> Result<(), UStatus> { - // Convert UMessage to TransmissionData - let transmission_data = match TransmissionData::from_message(&message) { - Ok(data) => data, - Err(e) => return Err(e), - }; + let transmission_data = TransmissionData::from_message(&message)?; - // Create custom header from UMessage attributes - let header = match CustomHeader::from_message(&message) { - Ok(header) => header, - Err(e) => return Err(e), - }; + let header = CustomHeader::from_message(&message)?; - // Send the message + // Loan sample and write payload let sample = publisher.loan_uninit() .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")))?; - let sample_final = sample - .write_payload(transmission_data); + let sample_final = sample.write_payload(transmission_data); sample_final.send() .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to send: {e}")))?; @@ -137,7 +115,6 @@ impl Iceoryx2Transport { } } -// The #[async_trait] attribute enables async functions in our trait impl. #[async_trait] impl UTransport for Iceoryx2Transport { async fn send(&self, message: UMessage) -> Result<(), UStatus> { @@ -204,8 +181,6 @@ mod tests { #[tokio::test] async fn test_transport_creation() { - // Test that we can create the transport without compilation errors - // Note: This might fail at runtime if iceoryx2 daemon isn't running match Iceoryx2Transport::new() { Ok(_transport) => println!("Transport created successfully"), Err(e) => println!("Transport creation failed (expected if daemon not running): {:?}", e), @@ -215,18 +190,21 @@ mod tests { #[tokio::test] async fn test_send_message() { if let Ok(transport) = Iceoryx2Transport::new() { - // Create a dummy UMessage + let uprotocol_header = CustomHeader { + version: 1, + timestamp: 123456789, + }; + let message = UMessage { attributes: MessageField::some(UAttributes::from(&uprotocol_header)), payload: Some(vec![1, 2, 3, 4].into()), ..Default::default() }; - // This will fail without iceoryx2 daemon, but should compile match transport.send(message).await { Ok(_) => println!("Message sent successfully"), Err(e) => println!("Send failed (expected without daemon): {:?}", e), } } } -} \ No newline at end of file +} From c83ca8d6507dc76fdd40957445b74bb55fc096a2 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 12 Jun 2025 15:13:52 -0400 Subject: [PATCH 04/42] seperated out the test cases from lib.rs and then made adjustment so that all the tests would work as expected --- src/custom_header.rs | 4 ++-- src/lib.rs | 34 +--------------------------------- src/test.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 35 deletions(-) create mode 100644 src/test.rs diff --git a/src/custom_header.rs b/src/custom_header.rs index 67cd948..e618851 100644 --- a/src/custom_header.rs +++ b/src/custom_header.rs @@ -26,8 +26,8 @@ impl CustomHeader { // Assuming UAttributes has a field called `fields` which is Vec<(String, String)> // Adjust if your actual UAttributes is different impl From<&CustomHeader> for UAttributes { - fn from(header: &CustomHeader) -> UAttributes { - let mut attrs = UAttributes::default(); + fn from(_header: &CustomHeader) -> UAttributes { + let attrs = UAttributes::default(); // Hypothetical code: add key-value pairs to attrs // Replace this with your real API to insert attributes diff --git a/src/lib.rs b/src/lib.rs index e924de3..68deaf3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,6 @@ use async_trait::async_trait; use std::sync::Arc; use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode, UAttributes}; use iceoryx2::prelude::*; -use protobuf::MessageField; mod custom_header; mod transmission_data; @@ -176,35 +175,4 @@ impl UTransport for Iceoryx2Transport { } #[cfg(test)] -mod tests { - use super::*; - - #[tokio::test] - async fn test_transport_creation() { - match Iceoryx2Transport::new() { - Ok(_transport) => println!("Transport created successfully"), - Err(e) => println!("Transport creation failed (expected if daemon not running): {:?}", e), - } - } - - #[tokio::test] - async fn test_send_message() { - if let Ok(transport) = Iceoryx2Transport::new() { - let uprotocol_header = CustomHeader { - version: 1, - timestamp: 123456789, - }; - - let message = UMessage { - attributes: MessageField::some(UAttributes::from(&uprotocol_header)), - payload: Some(vec![1, 2, 3, 4].into()), - ..Default::default() - }; - - match transport.send(message).await { - Ok(_) => println!("Message sent successfully"), - Err(e) => println!("Send failed (expected without daemon): {:?}", e), - } - } - } -} +mod test; \ No newline at end of file diff --git a/src/test.rs b/src/test.rs new file mode 100644 index 0000000..c55da55 --- /dev/null +++ b/src/test.rs @@ -0,0 +1,41 @@ +// src/test.rs + +use super::*; +use protobuf::MessageField; // if you use this in tests + +// Example synchronous test (no async needed) +#[test] +fn test_custom_header_from_user_header() { + let header = CustomHeader { version: 2, timestamp: 1000 }; + let new_header = CustomHeader::from_user_header(&header).unwrap(); + assert_eq!(new_header.version, 2); + assert_eq!(new_header.timestamp, 1000); +} + +// Async test requires Tokio runtime +#[tokio::test] +async fn test_transport_creation() { + let transport = Iceoryx2Transport::new(); + assert!(transport.is_ok()); +} + +#[tokio::test] +async fn test_send_message() { + if let Ok(transport) = Iceoryx2Transport::new() { + let uprotocol_header = CustomHeader { + version: 1, + timestamp: 123456789, + }; + + let message = UMessage { + attributes: MessageField::some(UAttributes::from(&uprotocol_header)), + payload: Some(vec![1, 2, 3, 4].into()), + ..Default::default() + }; + + let result = transport.send(message).await; + + // It might fail if no background service is running, so accept Ok or Err. + assert!(result.is_ok() || result.is_err()); + } +} From aa81d20f05864cc183a1986dc0c9e77fdd788dbe Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 12 Jun 2025 15:51:45 -0400 Subject: [PATCH 05/42] added custom header case & muliple messages in seq case --- src/test.rs | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/test.rs b/src/test.rs index c55da55..5b5d67b 100644 --- a/src/test.rs +++ b/src/test.rs @@ -3,7 +3,7 @@ use super::*; use protobuf::MessageField; // if you use this in tests -// Example synchronous test (no async needed) +// Example synchronous test (no async needed) -works #[test] fn test_custom_header_from_user_header() { let header = CustomHeader { version: 2, timestamp: 1000 }; @@ -12,14 +12,52 @@ fn test_custom_header_from_user_header() { assert_eq!(new_header.timestamp, 1000); } -// Async test requires Tokio runtime +// Async test requires Tokio runtime - work #[tokio::test] async fn test_transport_creation() { let transport = Iceoryx2Transport::new(); assert!(transport.is_ok()); } +//checks that custom header w missing fields works fine - works +#[test] +fn test_custom_header_missing_fields() { + let msg = UMessage::new(); // No attributes set + let result = CustomHeader::from_message(&msg); + assert!(result.is_ok()); // Still shouldn't panic +} + +//checks multiple messages which are sent in sequence - works #[tokio::test] +async fn test_multiple_sends() { + let transport = Iceoryx2Transport::new().unwrap(); + + for i in 0..5 { + //creating valid transmission data instance + let data = TransmissionData { + x: i, + y: i * 10, + funky: i as f64 + 0.5, + }; + + // convert to bytes + let bytes = data.to_bytes(); + + // wrap in umessage and send + let mut msg = UMessage::new(); + msg.payload = Some(bytes.into()); + + let result = transport.send(msg).await; + + if let Err(e) = &result { + } + + assert!(result.is_ok()); + } +} + + +#[tokio::test] // works async fn test_send_message() { if let Ok(transport) = Iceoryx2Transport::new() { let uprotocol_header = CustomHeader { From 89596de183b473c1ed6763c50126fc68255d8926 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 12 Jun 2025 15:57:55 -0400 Subject: [PATCH 06/42] checks that the umessage is correctly parsed into the transmission data test added and runs --- src/test.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/test.rs b/src/test.rs index 5b5d67b..47219ca 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,6 +1,8 @@ // src/test.rs use super::*; +use bytes::Bytes; + use protobuf::MessageField; // if you use this in tests // Example synchronous test (no async needed) -works @@ -19,6 +21,27 @@ async fn test_transport_creation() { assert!(transport.is_ok()); } +//checks that umessage is correctly parsed into transmission data +#[test] +fn test_transmission_data_from_message() { + let data = TransmissionData { + x: 42, + y: -7, + funky: 3.14, + }; + + let bytes = data.to_bytes(); + let mut msg = UMessage::new(); + msg.payload = Some(Bytes::from(bytes)); + + let result = TransmissionData::from_message(&msg); + assert!(result.is_ok()); + let decoded = result.unwrap(); + assert_eq!(decoded.x, 42); + assert_eq!(decoded.y, -7); + assert!((decoded.funky - 3.14).abs() < 1e-6); +} + //checks that custom header w missing fields works fine - works #[test] fn test_custom_header_missing_fields() { From fff54b70b8e7f53eb6fc417e58839a89118eccc8 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 12 Jun 2025 16:02:22 -0400 Subject: [PATCH 07/42] tested sending w empty payload, no payload, and max size payload --- src/test.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/test.rs b/src/test.rs index 47219ca..7a6d2ba 100644 --- a/src/test.rs +++ b/src/test.rs @@ -21,7 +21,7 @@ async fn test_transport_creation() { assert!(transport.is_ok()); } -//checks that umessage is correctly parsed into transmission data +//checks that umessage is correctly parsed into transmission data - works #[test] fn test_transmission_data_from_message() { let data = TransmissionData { @@ -79,6 +79,52 @@ async fn test_multiple_sends() { } } +//sending an empty payload - works +#[tokio::test] +async fn test_send_empty_payload() { + let transport = Iceoryx2Transport::new().unwrap(); + + let message = UMessage { + payload: Some(Bytes::from(vec![])), // empty payload + ..Default::default() + }; + + let result = transport.send(message).await; + + // It might be valid or invalid depending on implementation + assert!(result.is_ok() || result.is_err()); +} + +//sending without a payload +#[tokio::test] +async fn test_send_no_payload() { + let transport = Iceoryx2Transport::new().unwrap(); + + let message = UMessage::default(); // no payload at all + + let result = transport.send(message).await; + + assert!(result.is_err(), "Expected error when sending without payload"); +} + +//sending a max_sized payload - +#[tokio::test] +async fn test_send_large_payload() { + let transport = Iceoryx2Transport::new().unwrap(); + + let max_size_payload = vec![0xAB; 1024 * 1024]; // 1MB + let message = UMessage { + payload: Some(Bytes::from(max_size_payload)), + ..Default::default() + }; + + let result = transport.send(message).await; + + assert!(result.is_ok() || result.is_err()); // depends on your transport's buffer limit +} + + + #[tokio::test] // works async fn test_send_message() { From d97041c14da13e96aea27b1b6ac0ae4d05deb4fb Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 12 Jun 2025 16:12:02 -0400 Subject: [PATCH 08/42] included the multiple concurent messages --- src/test.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/test.rs b/src/test.rs index 7a6d2ba..a1db7f2 100644 --- a/src/test.rs +++ b/src/test.rs @@ -2,6 +2,7 @@ use super::*; use bytes::Bytes; +use std::sync::Arc; use protobuf::MessageField; // if you use this in tests @@ -95,7 +96,7 @@ async fn test_send_empty_payload() { assert!(result.is_ok() || result.is_err()); } -//sending without a payload +//sending without a payload - works #[tokio::test] async fn test_send_no_payload() { let transport = Iceoryx2Transport::new().unwrap(); @@ -107,7 +108,7 @@ async fn test_send_no_payload() { assert!(result.is_err(), "Expected error when sending without payload"); } -//sending a max_sized payload - +//sending a max_sized payload - works #[tokio::test] async fn test_send_large_payload() { let transport = Iceoryx2Transport::new().unwrap(); @@ -123,6 +124,33 @@ async fn test_send_large_payload() { assert!(result.is_ok() || result.is_err()); // depends on your transport's buffer limit } +//sending multiple concurrent messages - works +#[tokio::test] +async fn test_concurrent_sends() { + let transport = Iceoryx2Transport::new().unwrap(); + let transport = Arc::new(transport); + + let mut handles = vec![]; + + for i in 0..10 { + let transport_clone = Arc::clone(&transport); + handles.push(tokio::spawn(async move { + let data = TransmissionData { + x: i, + y: i * 2, + funky: i as f64 * 1.1, + }; + let mut msg = UMessage::new(); + msg.payload = Some(Bytes::from(data.to_bytes())); + transport_clone.send(msg).await + })); + } + + for handle in handles { + let result = handle.await.unwrap(); + assert!(result.is_ok()); + } +} From ee5116faf55d88958a2a5e9b81c11e1e528e4341 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Fri, 13 Jun 2025 11:52:50 -0400 Subject: [PATCH 09/42] adding all files so can merge into one shared fork --- Cargo.lock | 77 +++++++++++++++++++++++++++++++++ Cargo.toml | 3 ++ src/custom_header.rs | 12 ++++++ src/lib.rs | 100 +++++++++++++++++++------------------------ src/test.rs | 4 +- 5 files changed, 137 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e96ac67..19a347c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + [[package]] name = "anyhow" version = "1.0.98" @@ -150,6 +156,12 @@ dependencies = [ "libloading", ] +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + [[package]] name = "either" version = "1.15.0" @@ -204,6 +216,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fragile" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" + [[package]] name = "getrandom" version = "0.2.16" @@ -551,6 +569,32 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "mockall" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "nom" version = "7.1.3" @@ -620,6 +664,32 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "predicates" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +dependencies = [ + "anstyle", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" + +[[package]] +name = "predicates-tree" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +dependencies = [ + "predicates-core", + "termtree", +] + [[package]] name = "prettyplease" version = "0.2.33" @@ -975,6 +1045,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + [[package]] name = "thiserror" version = "1.0.69" @@ -1106,6 +1182,7 @@ dependencies = [ "async-trait", "bytes", "mediatype", + "mockall", "protobuf", "protobuf-codegen", "protoc-bin-vendored", diff --git a/Cargo.toml b/Cargo.toml index e61bce6..338d727 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,6 @@ async-trait = "0.1" protobuf = "3.7.2" bytes = "1.10.1" tokio = { version = "1", features = ["full"] } + +[dev-dependencies] +up-rust = { version = "0.5.0", features = ["test-util"] } diff --git a/src/custom_header.rs b/src/custom_header.rs index e618851..b9b504c 100644 --- a/src/custom_header.rs +++ b/src/custom_header.rs @@ -40,3 +40,15 @@ impl From<&CustomHeader> for UAttributes { attrs } } + +#[cfg(test)] +mod tests{ +use super::*; +#[test] +fn test_custom_header_from_user_header() { + let header = CustomHeader { version: 2, timestamp: 1000 }; + let new_header = CustomHeader::from_user_header(&header).unwrap(); + assert_eq!(new_header.version, 2); + assert_eq!(new_header.timestamp, 1000); +} +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 68deaf3..b45f8e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -114,65 +114,53 @@ impl Iceoryx2Transport { } } -#[async_trait] -impl UTransport for Iceoryx2Transport { - async fn send(&self, message: UMessage) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::Send { - message, - response: tx, - }; - - self.command_sender.send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - rx.recv() - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? - } +async fn register_listener( + &segilf, + source_filter: &UUri, + sink_filter: Option<&UUri>, + _listener: Arc, +) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); - async fn register_listener( - &self, - source_filter: &UUri, - sink_filter: Option<&UUri>, - _listener: Arc, - ) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::RegisterListener { - source_filter: source_filter.clone(), - sink_filter: sink_filter.cloned(), - response: tx, - }; - - self.command_sender.send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - rx.recv() - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? - } + let command = TransportCommand::RegisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + response: tx, + }; - async fn unregister_listener( - &self, - source_filter: &UUri, - sink_filter: Option<&UUri>, - _listener: Arc, - ) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::UnregisterListener { - source_filter: source_filter.clone(), - sink_filter: sink_filter.cloned(), - response: tx, - }; - - self.command_sender.send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - rx.recv() - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? - } + self.command_sender.send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + let status: Result<(), UStatus> = rx.recv() + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))?; + + status // just return the Result<(), UStatus> you got here } +async fn unregister_listener( + &self, + source_filter: &UUri, + sink_filter: Option<&UUri>, + _listener: Arc, +) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::UnregisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + response: tx, + }; + + self.command_sender.send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + let status: Result<(), UStatus> = rx.recv() + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))?; + + status // return the result directly +} + + + #[cfg(test)] mod test; \ No newline at end of file diff --git a/src/test.rs b/src/test.rs index a1db7f2..8175901 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,5 +1,3 @@ -// src/test.rs - use super::*; use bytes::Bytes; use std::sync::Arc; @@ -173,4 +171,4 @@ async fn test_send_message() { // It might fail if no background service is running, so accept Ok or Err. assert!(result.is_ok() || result.is_err()); } -} +} \ No newline at end of file From a525b97f60cfcc468bf514d4670017fbe5287bf6 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Mon, 23 Jun 2025 16:47:24 -0500 Subject: [PATCH 10/42] tests run and there are not issues anymore which prevent them from running --- src/lib.rs | 98 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b45f8e6..e444535 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,17 @@ use async_trait::async_trait; +use up_rust::UAttributes; use std::sync::Arc; -use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode, UAttributes}; +use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode}; use iceoryx2::prelude::*; mod custom_header; mod transmission_data; pub use custom_header::CustomHeader; -pub use transmission_data::TransmissionData; +pub use transmission_data::TransmissionData; use std::thread; +use std::pin::Pin; +use std::future::Future; #[derive(Debug)] enum TransportCommand { @@ -99,7 +102,7 @@ impl Iceoryx2Transport { ) -> Result<(), UStatus> { let transmission_data = TransmissionData::from_message(&message)?; - let header = CustomHeader::from_message(&message)?; + let _header = CustomHeader::from_message(&message)?; // Loan sample and write payload let sample = publisher.loan_uninit() @@ -114,53 +117,68 @@ impl Iceoryx2Transport { } } -async fn register_listener( - &segilf, - source_filter: &UUri, - sink_filter: Option<&UUri>, - _listener: Arc, -) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); +#[async_trait] +impl UTransport for Iceoryx2Transport { + async fn send(&self, message: UMessage) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); - let command = TransportCommand::RegisterListener { - source_filter: source_filter.clone(), - sink_filter: sink_filter.cloned(), - response: tx, - }; + let command = TransportCommand::Send { + message, + response: tx, + }; - self.command_sender.send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + self.command_sender.send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - let status: Result<(), UStatus> = rx.recv() - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))?; + // Flatten nested Result, _> to Result<(), UStatus> + rx.recv() + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? + } - status // just return the Result<(), UStatus> you got here -} + async fn register_listener( + &self, + source_filter: &UUri, + sink_filter: Option<&UUri>, + listener: Arc, + ) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); -async fn unregister_listener( - &self, - source_filter: &UUri, - sink_filter: Option<&UUri>, - _listener: Arc, -) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); + let command = TransportCommand::RegisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + response: tx, + }; - let command = TransportCommand::UnregisterListener { - source_filter: source_filter.clone(), - sink_filter: sink_filter.cloned(), - response: tx, - }; + self.command_sender.send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - self.command_sender.send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + // Flatten nested Result, _> to Result<(), UStatus> + rx.recv() + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? + } - let status: Result<(), UStatus> = rx.recv() - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))?; + async fn unregister_listener( + &self, + source_filter: &UUri, + sink_filter: Option<&UUri>, + listener: Arc, + ) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); - status // return the result directly -} + let command = TransportCommand::UnregisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + response: tx, + }; + self.command_sender.send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + // Flatten nested Result, _> to Result<(), UStatus> + rx.recv() + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? + } +} #[cfg(test)] -mod test; \ No newline at end of file +mod test; From 761c7d7f9475c38cf734b06c31e3a889f99a7c20 Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Fri, 27 Jun 2025 18:55:46 +0530 Subject: [PATCH 11/42] skeleton code for receiver testing --- src/receiver.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/receiver.rs diff --git a/src/receiver.rs b/src/receiver.rs new file mode 100644 index 0000000..30cd4d9 --- /dev/null +++ b/src/receiver.rs @@ -0,0 +1,46 @@ +use super::*; +use bytes::Bytes; +use std::sync::Arc; + +use async_trait::async_trait; +use up_rust::UAttributes; +use std::sync::Arc; +use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode}; +use iceoryx2::prelude::*; +use tokio::sync::mpsc::UnboundedSender; + + +pub struct Receiver{ + +} + +impl Receiver{ + pub fn new() -> Self{ + Self{ + + } + } +} + +#[async_trait] +impl UListener for Receiver{ + async fn on_receive(&self,message:UMessage)->UStatus{ + if let Some(payload)=message.payload(){ + println!("Receieved Message ID: {}", message.id()); + } + + UStatus::Ok + } +} + +#[tokio::test] +async fn test_receiver(){ + let receiver= Receiver::new(); + let transport = Iceoryx2Transport::new().unwrap(); + source_URI= UUri + sink_filter= + transport.register_listener(receiver).await.unwrap(); + +} + + From 2a4e05017d24f35fbd2bea72c2ef15bbcd316b69 Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Mon, 30 Jun 2025 00:48:28 +0530 Subject: [PATCH 12/42] receiver test with compilation errors --- .DS_Store | Bin 0 -> 6148 bytes src/receiver.rs | 68 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0, } impl Receiver{ - pub fn new() -> Self{ - Self{ - + pub fn new(expected: UMessage,notify: Arc) -> Self{ + Self{ expected,notify } } } @@ -27,20 +28,67 @@ impl UListener for Receiver{ async fn on_receive(&self,message:UMessage)->UStatus{ if let Some(payload)=message.payload(){ println!("Receieved Message ID: {}", message.id()); + assert_eq!(self.expected, message); + self.notify.notify_one(); } UStatus::Ok } } -#[tokio::test] -async fn test_receiver(){ - let receiver= Receiver::new(); +async fn register_listener_and_send( + authority: &str, + umessage: UMessage, + source_filter: &UUri, + sink_filter: Option<&UUri>, +) -> Result<(), Box> { + let source_uri= UUri::try_from_parts(authority, 0xABC, 1, 0)?; let transport = Iceoryx2Transport::new().unwrap(); - source_URI= UUri - sink_filter= - transport.register_listener(receiver).await.unwrap(); + let notify = Arc::new(Notify::new()); + let receiver=Arc::new(Receiver::new(umessage.clone(),notify.clone())); + + // [itest->dsn~supported-message-delivery-methods~1] + transport + .register_listener(source_filter, sink_filter, receiver) + .await.unwrap(); + + // Send UMessage + info!( + "sending message: [id: {}, type: {}]", + umessage.id_unchecked().to_hyphenated_string(), + umessage.type_unchecked().to_cloudevent_type() + ); + transport.send(umessage).await?; + Ok( + tokio::time::timeout(Duration::from_secs(3), notify.notified()) + .await + .map_err(|_| { + UStatus::fail_with_code(UCode::DEADLINE_EXCEEDED, "did not receive message in time") + })?, + ) +} + +#[test_case::test_case("vehicle1", 12_000, "//vehicle1/10A10B/1/CA5D", "//vehicle1/10A10B/1/CA5D"; "specific source filter")] +// [utest->dsn~up-attributes-ttl~1] +#[test_case::test_case("vehicle1", 0, "/D5A/3/9999", "//vehicle1/D5A/3/FFFF"; "source filter with wildcard resource ID")] +#[test_case::test_case("vehicle1", 12_000, "//vehicle1/70222/2/8001", "//*/FFFF0222/2/8001"; "source filter with wildcard authority and service instance ID")] +#[tokio::test(flavor = "multi_thread")] +async fn test_publish_gets_to_listener( + authority: &str, + ttl: u32, + topic_uri: &str, + source_filter_uri: &str, +) -> Result<(), Box> { + let topic = UUri::from_str(topic_uri)?; + let source_filter = UUri::from_str(source_filter_uri)?; + let umessage = UMessageBuilder::publish(topic.clone()) + .with_priority(up_rust::UPriority::UPRIORITY_CS5) + .with_traceparent("traceparent") + .with_ttl(ttl) + .build_with_payload(MESSAGE_DATA, UPayloadFormat::UPAYLOAD_FORMAT_TEXT)?; + register_listener_and_send(authority, umessage, &source_filter, None).await } + From 2e2ba859be4c8cf5c71878d46eb9307ce891749f Mon Sep 17 00:00:00 2001 From: Noella Horo Date: Tue, 1 Jul 2025 00:19:27 +0530 Subject: [PATCH 13/42] modifed send test cases for muli sends, implemented send(), written a compute service name fuction --- .github/workflows/check.yml | 38 +- .gitignore | 2 +- Cargo.lock | 3064 +++++++++++++++++------------------ Cargo.toml | 30 +- README.md | 4 +- src/custom_header.rs | 106 +- src/lib.rs | 402 ++--- src/receiver.rs | 92 +- src/test.rs | 361 +++-- src/transmission_data.rs | 122 +- 10 files changed, 2135 insertions(+), 2086 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index cc91e27..3ab9ccb 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,20 +1,20 @@ -name: Rust Project CI - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build_and_test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Build - run: cargo build --verbose - - - name: Run tests +name: Rust Project CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build_and_test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: cargo build --verbose + + - name: Run tests run: cargo test --verbose \ No newline at end of file diff --git a/.gitignore b/.gitignore index ea8c4bf..0b42d2d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/target +/target diff --git a/Cargo.lock b/Cargo.lock index 19a347c..5bdade1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,1532 +1,1532 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstyle" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" - -[[package]] -name = "anyhow" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" - -[[package]] -name = "async-trait" -version = "0.1.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", - "which", -] - -[[package]] -name = "bitflags" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "cc" -version = "1.2.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" -dependencies = [ - "shlex", -] - -[[package]] -name = "cdr" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9617422bf43fde9280707a7e90f8f7494389c182f5c70b0f67592d0f06d41dfa" -dependencies = [ - "byteorder", - "serde", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "downcast" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "enum-iterator" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635" -dependencies = [ - "enum-iterator-derive", -] - -[[package]] -name = "enum-iterator-derive" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "fragile" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - -[[package]] -name = "hashbrown" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" - -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "iceoryx2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a462c1baccde41be91001f7b36cb1d1afe313c2afdb5a6c16174ae7ca917b6ef" -dependencies = [ - "iceoryx2-bb-container", - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-lock-free", - "iceoryx2-bb-log", - "iceoryx2-bb-memory", - "iceoryx2-bb-posix", - "iceoryx2-bb-system-types", - "iceoryx2-cal", - "iceoryx2-pal-concurrency-sync", - "serde", - "tiny-fn", - "toml", -] - -[[package]] -name = "iceoryx2-bb-container" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6205871fd23e67215ec4dff6b9895f7526325b498b2eb759b93399ee69d6d89" -dependencies = [ - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-log", - "iceoryx2-pal-concurrency-sync", - "serde", -] - -[[package]] -name = "iceoryx2-bb-derive-macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "468faacface5d0252a090d565d9da86c05dc77e822abebdc0affeaad9021cce6" -dependencies = [ - "iceoryx2-bb-elementary", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "iceoryx2-bb-elementary" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af6479bb3aed7cfb398e54e91a769629d64f5bc2ede8c6a528ee02daa1675a5" -dependencies = [ - "iceoryx2-bb-elementary-traits", - "iceoryx2-pal-concurrency-sync", -] - -[[package]] -name = "iceoryx2-bb-elementary-traits" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb55d8c8b866531332904fd5a7041355d67d91d722f2e22850c1364ca779d30" -dependencies = [ - "iceoryx2-pal-concurrency-sync", -] - -[[package]] -name = "iceoryx2-bb-lock-free" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9e850529efc04e4f70789fc8a8016883cda0ee9b88a078f0b6d296cc966b11" -dependencies = [ - "iceoryx2-bb-elementary", - "iceoryx2-bb-log", - "iceoryx2-pal-concurrency-sync", -] - -[[package]] -name = "iceoryx2-bb-log" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54d933cadfd6ac326dbce588fa5e1203b1b85234899a1742ad16a64490631dd" -dependencies = [ - "iceoryx2-pal-concurrency-sync", - "termsize", -] - -[[package]] -name = "iceoryx2-bb-memory" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b03e120e45d869979da01f894c226ed24c49feb3a318acbb7106021962d205" -dependencies = [ - "iceoryx2-bb-elementary", - "iceoryx2-bb-lock-free", - "iceoryx2-bb-log", - "iceoryx2-bb-posix", - "iceoryx2-pal-concurrency-sync", -] - -[[package]] -name = "iceoryx2-bb-posix" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc53c019df6e0aa5df7bf8052cc11064a4ba19fe7bc34671f8ce13c2eb7ac3ab" -dependencies = [ - "enum-iterator", - "iceoryx2-bb-container", - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-log", - "iceoryx2-bb-system-types", - "iceoryx2-pal-concurrency-sync", - "iceoryx2-pal-configuration", - "iceoryx2-pal-posix", - "lazy_static", - "serde", - "tiny-fn", -] - -[[package]] -name = "iceoryx2-bb-system-types" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346e9593393627c2cbc17b8663a0650c8e33377276f2e06e10346816705ae5cb" -dependencies = [ - "iceoryx2-bb-container", - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-log", - "iceoryx2-pal-configuration", - "iceoryx2-pal-posix", - "serde", -] - -[[package]] -name = "iceoryx2-cal" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9941d8beb989b80b581d2a6871e4b464b695bc1f86076117be1eb9c74f3dcb" -dependencies = [ - "cdr", - "iceoryx2-bb-container", - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-lock-free", - "iceoryx2-bb-log", - "iceoryx2-bb-memory", - "iceoryx2-bb-posix", - "iceoryx2-bb-system-types", - "iceoryx2-pal-concurrency-sync", - "once_cell", - "serde", - "sha1_smol", - "tiny-fn", - "toml", -] - -[[package]] -name = "iceoryx2-pal-concurrency-sync" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bc07c3be1bce2afef70dc5597abe14bdadde367f759243e92325a96733163d6" - -[[package]] -name = "iceoryx2-pal-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a94e78e84f673da8ee4b46cb5df643792b046b7118678da9969fee29cf15c68" - -[[package]] -name = "iceoryx2-pal-posix" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5616e41d3171df75d1ab9577d5bccdc4fb95102e275db2afd84a9828a0a01918" -dependencies = [ - "bindgen", - "cc", - "iceoryx2-pal-concurrency-sync", - "iceoryx2-pal-configuration", - "lazy_static", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "indexmap" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.0", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "lock_api" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "mediatype" -version = "0.19.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33746aadcb41349ec291e7f2f0a3aa6834d1d7c58066fb4b01f68efc4c4b7631" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" -dependencies = [ - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] - -[[package]] -name = "mockall" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "mockall_derive", - "predicates", - "predicates-tree", -] - -[[package]] -name = "mockall_derive" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "outref" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" - -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "predicates" -version = "3.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" -dependencies = [ - "anstyle", - "predicates-core", -] - -[[package]] -name = "predicates-core" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" - -[[package]] -name = "predicates-tree" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" -dependencies = [ - "predicates-core", - "termtree", -] - -[[package]] -name = "prettyplease" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "protobuf" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" -dependencies = [ - "bytes", - "once_cell", - "protobuf-support", - "thiserror", -] - -[[package]] -name = "protobuf-codegen" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3976825c0014bbd2f3b34f0001876604fe87e0c86cd8fa54251530f1544ace" -dependencies = [ - "anyhow", - "once_cell", - "protobuf", - "protobuf-parse", - "regex", - "tempfile", - "thiserror", -] - -[[package]] -name = "protobuf-parse" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" -dependencies = [ - "anyhow", - "indexmap", - "log", - "protobuf", - "protobuf-support", - "tempfile", - "thiserror", - "which", -] - -[[package]] -name = "protobuf-support" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" -dependencies = [ - "thiserror", -] - -[[package]] -name = "protoc-bin-vendored" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd89a830d0eab2502c81a9b8226d446a52998bb78e5e33cb2637c0cdd6068d99" -dependencies = [ - "protoc-bin-vendored-linux-aarch_64", - "protoc-bin-vendored-linux-ppcle_64", - "protoc-bin-vendored-linux-x86_32", - "protoc-bin-vendored-linux-x86_64", - "protoc-bin-vendored-macos-aarch_64", - "protoc-bin-vendored-macos-x86_64", - "protoc-bin-vendored-win32", -] - -[[package]] -name = "protoc-bin-vendored-linux-aarch_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f563627339f1653ea1453dfbcb4398a7369b768925eb14499457aeaa45afe22c" - -[[package]] -name = "protoc-bin-vendored-linux-ppcle_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5025c949a02cd3b60c02501dd0f348c16e8fff464f2a7f27db8a9732c608b746" - -[[package]] -name = "protoc-bin-vendored-linux-x86_32" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9500ce67d132c2f3b572504088712db715755eb9adf69d55641caa2cb68a07" - -[[package]] -name = "protoc-bin-vendored-linux-x86_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5462592380cefdc9f1f14635bcce70ba9c91c1c2464c7feb2ce564726614cc41" - -[[package]] -name = "protoc-bin-vendored-macos-aarch_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c637745681b68b4435484543667a37606c95ddacf15e917710801a0877506030" - -[[package]] -name = "protoc-bin-vendored-macos-x86_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38943f3c90319d522f94a6dfd4a134ba5e36148b9506d2d9723a82ebc57c8b55" - -[[package]] -name = "protoc-bin-vendored-win32" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc55d7dec32ecaf61e0bd90b3d2392d721a28b95cfd23c3e176eccefbeab2f2" - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "redox_syscall" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" -dependencies = [ - "libc", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "syn" -version = "2.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix 1.0.7", - "windows-sys 0.59.0", -] - -[[package]] -name = "termsize" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f11ff5c25c172608d5b85e2fb43ee9a6d683a7f4ab7f96ae07b3d8b590368fd" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "termtree" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tiny-fn" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fde9a76dac5751480f711f327371c809d7f8a9f036436e6237d67859adbf3bd" - -[[package]] -name = "tokio" -version = "1.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-macros" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "log", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "up-rust" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616da735a2c488128e67d5ce16113f4303c83a5dbeb7c281ae893da281df2a57" -dependencies = [ - "async-trait", - "bytes", - "mediatype", - "mockall", - "protobuf", - "protobuf-codegen", - "protoc-bin-vendored", - "rand", - "thiserror", - "tokio", - "tracing", - "uriparse", - "uuid-simd", -] - -[[package]] -name = "up-transport-iceoryx2-rust" -version = "0.1.0" -dependencies = [ - "async-trait", - "bytes", - "iceoryx2", - "protobuf", - "tokio", - "up-rust", -] - -[[package]] -name = "uriparse" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" -dependencies = [ - "fnv", - "lazy_static", -] - -[[package]] -name = "uuid-simd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" -dependencies = [ - "outref", - "vsimd", -] - -[[package]] -name = "vsimd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" -dependencies = [ - "wit-bindgen-rt", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "winnow" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] - -[[package]] -name = "zerocopy" -version = "0.8.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" +dependencies = [ + "shlex", +] + +[[package]] +name = "cdr" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9617422bf43fde9280707a7e90f8f7494389c182f5c70b0f67592d0f06d41dfa" +dependencies = [ + "byteorder", + "serde", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "enum-iterator" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fragile" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "iceoryx2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a462c1baccde41be91001f7b36cb1d1afe313c2afdb5a6c16174ae7ca917b6ef" +dependencies = [ + "iceoryx2-bb-container", + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-lock-free", + "iceoryx2-bb-log", + "iceoryx2-bb-memory", + "iceoryx2-bb-posix", + "iceoryx2-bb-system-types", + "iceoryx2-cal", + "iceoryx2-pal-concurrency-sync", + "serde", + "tiny-fn", + "toml", +] + +[[package]] +name = "iceoryx2-bb-container" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6205871fd23e67215ec4dff6b9895f7526325b498b2eb759b93399ee69d6d89" +dependencies = [ + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", + "iceoryx2-pal-concurrency-sync", + "serde", +] + +[[package]] +name = "iceoryx2-bb-derive-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468faacface5d0252a090d565d9da86c05dc77e822abebdc0affeaad9021cce6" +dependencies = [ + "iceoryx2-bb-elementary", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "iceoryx2-bb-elementary" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af6479bb3aed7cfb398e54e91a769629d64f5bc2ede8c6a528ee02daa1675a5" +dependencies = [ + "iceoryx2-bb-elementary-traits", + "iceoryx2-pal-concurrency-sync", +] + +[[package]] +name = "iceoryx2-bb-elementary-traits" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb55d8c8b866531332904fd5a7041355d67d91d722f2e22850c1364ca779d30" +dependencies = [ + "iceoryx2-pal-concurrency-sync", +] + +[[package]] +name = "iceoryx2-bb-lock-free" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9e850529efc04e4f70789fc8a8016883cda0ee9b88a078f0b6d296cc966b11" +dependencies = [ + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", + "iceoryx2-pal-concurrency-sync", +] + +[[package]] +name = "iceoryx2-bb-log" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54d933cadfd6ac326dbce588fa5e1203b1b85234899a1742ad16a64490631dd" +dependencies = [ + "iceoryx2-pal-concurrency-sync", + "termsize", +] + +[[package]] +name = "iceoryx2-bb-memory" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45b03e120e45d869979da01f894c226ed24c49feb3a318acbb7106021962d205" +dependencies = [ + "iceoryx2-bb-elementary", + "iceoryx2-bb-lock-free", + "iceoryx2-bb-log", + "iceoryx2-bb-posix", + "iceoryx2-pal-concurrency-sync", +] + +[[package]] +name = "iceoryx2-bb-posix" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc53c019df6e0aa5df7bf8052cc11064a4ba19fe7bc34671f8ce13c2eb7ac3ab" +dependencies = [ + "enum-iterator", + "iceoryx2-bb-container", + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", + "iceoryx2-bb-system-types", + "iceoryx2-pal-concurrency-sync", + "iceoryx2-pal-configuration", + "iceoryx2-pal-posix", + "lazy_static", + "serde", + "tiny-fn", +] + +[[package]] +name = "iceoryx2-bb-system-types" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346e9593393627c2cbc17b8663a0650c8e33377276f2e06e10346816705ae5cb" +dependencies = [ + "iceoryx2-bb-container", + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", + "iceoryx2-pal-configuration", + "iceoryx2-pal-posix", + "serde", +] + +[[package]] +name = "iceoryx2-cal" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9941d8beb989b80b581d2a6871e4b464b695bc1f86076117be1eb9c74f3dcb" +dependencies = [ + "cdr", + "iceoryx2-bb-container", + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-lock-free", + "iceoryx2-bb-log", + "iceoryx2-bb-memory", + "iceoryx2-bb-posix", + "iceoryx2-bb-system-types", + "iceoryx2-pal-concurrency-sync", + "once_cell", + "serde", + "sha1_smol", + "tiny-fn", + "toml", +] + +[[package]] +name = "iceoryx2-pal-concurrency-sync" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bc07c3be1bce2afef70dc5597abe14bdadde367f759243e92325a96733163d6" + +[[package]] +name = "iceoryx2-pal-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a94e78e84f673da8ee4b46cb5df643792b046b7118678da9969fee29cf15c68" + +[[package]] +name = "iceoryx2-pal-posix" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5616e41d3171df75d1ab9577d5bccdc4fb95102e275db2afd84a9828a0a01918" +dependencies = [ + "bindgen", + "cc", + "iceoryx2-pal-concurrency-sync", + "iceoryx2-pal-configuration", + "lazy_static", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.0", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "mediatype" +version = "0.19.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33746aadcb41349ec291e7f2f0a3aa6834d1d7c58066fb4b01f68efc4c4b7631" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "mockall" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "predicates" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +dependencies = [ + "anstyle", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" + +[[package]] +name = "predicates-tree" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "prettyplease" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protobuf" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" +dependencies = [ + "bytes", + "once_cell", + "protobuf-support", + "thiserror", +] + +[[package]] +name = "protobuf-codegen" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3976825c0014bbd2f3b34f0001876604fe87e0c86cd8fa54251530f1544ace" +dependencies = [ + "anyhow", + "once_cell", + "protobuf", + "protobuf-parse", + "regex", + "tempfile", + "thiserror", +] + +[[package]] +name = "protobuf-parse" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" +dependencies = [ + "anyhow", + "indexmap", + "log", + "protobuf", + "protobuf-support", + "tempfile", + "thiserror", + "which", +] + +[[package]] +name = "protobuf-support" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" +dependencies = [ + "thiserror", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd89a830d0eab2502c81a9b8226d446a52998bb78e5e33cb2637c0cdd6068d99" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-aarch_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f563627339f1653ea1453dfbcb4398a7369b768925eb14499457aeaa45afe22c" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5025c949a02cd3b60c02501dd0f348c16e8fff464f2a7f27db8a9732c608b746" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9500ce67d132c2f3b572504088712db715755eb9adf69d55641caa2cb68a07" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5462592380cefdc9f1f14635bcce70ba9c91c1c2464c7feb2ce564726614cc41" + +[[package]] +name = "protoc-bin-vendored-macos-aarch_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c637745681b68b4435484543667a37606c95ddacf15e917710801a0877506030" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38943f3c90319d522f94a6dfd4a134ba5e36148b9506d2d9723a82ebc57c8b55" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dc55d7dec32ecaf61e0bd90b3d2392d721a28b95cfd23c3e176eccefbeab2f2" + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "redox_syscall" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "syn" +version = "2.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.0.7", + "windows-sys 0.59.0", +] + +[[package]] +name = "termsize" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f11ff5c25c172608d5b85e2fb43ee9a6d683a7f4ab7f96ae07b3d8b590368fd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiny-fn" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fde9a76dac5751480f711f327371c809d7f8a9f036436e6237d67859adbf3bd" + +[[package]] +name = "tokio" +version = "1.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "up-rust" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616da735a2c488128e67d5ce16113f4303c83a5dbeb7c281ae893da281df2a57" +dependencies = [ + "async-trait", + "bytes", + "mediatype", + "mockall", + "protobuf", + "protobuf-codegen", + "protoc-bin-vendored", + "rand", + "thiserror", + "tokio", + "tracing", + "uriparse", + "uuid-simd", +] + +[[package]] +name = "up-transport-iceoryx2-rust" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "iceoryx2", + "protobuf", + "tokio", + "up-rust", +] + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "uuid-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" +dependencies = [ + "outref", + "vsimd", +] + +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 338d727..3d01ebe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,15 @@ -[package] -name = "up-transport-iceoryx2-rust" -version = "0.1.0" -edition = "2024" - -[dependencies] -up-rust = "0.5" -iceoryx2 = "0.6.1" -async-trait = "0.1" -protobuf = "3.7.2" -bytes = "1.10.1" -tokio = { version = "1", features = ["full"] } - -[dev-dependencies] -up-rust = { version = "0.5.0", features = ["test-util"] } +[package] +name = "up-transport-iceoryx2-rust" +version = "0.1.0" +edition = "2024" + +[dependencies] +up-rust = "0.5" +iceoryx2 = "0.6.1" +async-trait = "0.1" +protobuf = "3.7.2" +bytes = "1.10.1" +tokio = { version = "1", features = ["full"] } + +[dev-dependencies] +up-rust = { version = "0.5.0", features = ["test-util"] } diff --git a/README.md b/README.md index 24159af..c65d78f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# up-transport-iceoryx2-rust -Rust uTransport implementation for iceoryx2 +# up-transport-iceoryx2-rust +Rust uTransport implementation for iceoryx2 diff --git a/src/custom_header.rs b/src/custom_header.rs index b9b504c..9f8d1fb 100644 --- a/src/custom_header.rs +++ b/src/custom_header.rs @@ -1,54 +1,54 @@ -use iceoryx2::prelude::*; -use up_rust::{UMessage, UStatus, UCode, UAttributes}; - -#[derive(Default, Debug, ZeroCopySend)] -#[type_name("CustomHeader")] -#[repr(C)] -pub struct CustomHeader { - pub version: i32, - pub timestamp: u64, -} - -impl CustomHeader { - pub fn from_user_header(header: &Self) -> Result { - Ok(Self { - version: header.version, - timestamp: header.timestamp, - }) - } - - pub fn from_message(_message: &UMessage) -> Result { - // For now, just default - Ok(Self::default()) - } -} - -// Assuming UAttributes has a field called `fields` which is Vec<(String, String)> -// Adjust if your actual UAttributes is different -impl From<&CustomHeader> for UAttributes { - fn from(_header: &CustomHeader) -> UAttributes { - let attrs = UAttributes::default(); - - // Hypothetical code: add key-value pairs to attrs - // Replace this with your real API to insert attributes - // For example, if UAttributes has a `fields` Vec<(String, String)>: - // attrs.fields.push(("version".to_string(), header.version.to_string())); - // attrs.fields.push(("timestamp".to_string(), header.timestamp.to_string())); - - // If no such field exists, just return default or implement accordingly - - attrs - } -} - -#[cfg(test)] -mod tests{ -use super::*; -#[test] -fn test_custom_header_from_user_header() { - let header = CustomHeader { version: 2, timestamp: 1000 }; - let new_header = CustomHeader::from_user_header(&header).unwrap(); - assert_eq!(new_header.version, 2); - assert_eq!(new_header.timestamp, 1000); -} +use iceoryx2::prelude::*; +use up_rust::{UMessage, UStatus, UCode, UAttributes}; + +#[derive(Default, Debug, ZeroCopySend)] +#[type_name("CustomHeader")] +#[repr(C)] +pub struct CustomHeader { + pub version: i32, + pub timestamp: u64, +} + +impl CustomHeader { + pub fn from_user_header(header: &Self) -> Result { + Ok(Self { + version: header.version, + timestamp: header.timestamp, + }) + } + + pub fn from_message(_message: &UMessage) -> Result { + // For now, just default + Ok(Self::default()) + } +} + +// Assuming UAttributes has a field called `fields` which is Vec<(String, String)> +// Adjust if your actual UAttributes is different +impl From<&CustomHeader> for UAttributes { + fn from(_header: &CustomHeader) -> UAttributes { + let attrs = UAttributes::default(); + + // Hypothetical code: add key-value pairs to attrs + // Replace this with your real API to insert attributes + // For example, if UAttributes has a `fields` Vec<(String, String)>: + // attrs.fields.push(("version".to_string(), header.version.to_string())); + // attrs.fields.push(("timestamp".to_string(), header.timestamp.to_string())); + + // If no such field exists, just return default or implement accordingly + + attrs + } +} + +#[cfg(test)] +mod tests{ +use super::*; +#[test] +fn test_custom_header_from_user_header() { + let header = CustomHeader { version: 2, timestamp: 1000 }; + let new_header = CustomHeader::from_user_header(&header).unwrap(); + assert_eq!(new_header.version, 2); + assert_eq!(new_header.timestamp, 1000); +} } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index e444535..1c4c315 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,184 +1,218 @@ -use async_trait::async_trait; -use up_rust::UAttributes; -use std::sync::Arc; -use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode}; -use iceoryx2::prelude::*; - -mod custom_header; -mod transmission_data; -pub use custom_header::CustomHeader; -pub use transmission_data::TransmissionData; - -use std::thread; -use std::pin::Pin; -use std::future::Future; - -#[derive(Debug)] -enum TransportCommand { - Send { - message: UMessage, - response: std::sync::mpsc::Sender> - }, - RegisterListener { - source_filter: UUri, - sink_filter: Option, - response: std::sync::mpsc::Sender>, - }, - UnregisterListener { - source_filter: UUri, - sink_filter: Option, - response: std::sync::mpsc::Sender>, - }, -} - -pub struct Iceoryx2Transport { - command_sender: std::sync::mpsc::Sender, -} - -impl Iceoryx2Transport { - pub fn new() -> Result { - let (tx, rx) = std::sync::mpsc::channel(); - - thread::spawn(move || { - Self::background_task(rx); - }); - - Ok(Self { - command_sender: tx, - }) - } - - fn background_task(rx: std::sync::mpsc::Receiver) { - let node = match NodeBuilder::new().create::() { - Ok(node) => node, - Err(e) => { - eprintln!("Failed to create iceoryx2 node: {}", e); - return; - } - }; - - let service = match node - .service_builder(&"My/Funk/ServiceName".try_into().unwrap()) - .publish_subscribe::() - .user_header::() - .open_or_create() - { - Ok(service) => service, - Err(e) => { - eprintln!("Failed to create iceoryx2 service: {}", e); - return; - } - }; - - let publisher = match service.publisher_builder().create() { - Ok(publisher) => publisher, - Err(e) => { - eprintln!("Failed to create iceoryx2 publisher: {}", e); - return; - } - }; - - while let Ok(command) = rx.recv() { - match command { - TransportCommand::Send { message, response } => { - let result = Self::handle_send(&publisher, message); - let _ = response.send(result); - } - TransportCommand::RegisterListener { response, .. } => { - // TODO: Implement listener registration - let _ = response.send(Ok(())); - } - TransportCommand::UnregisterListener { response, .. } => { - // TODO: Implement listener unregistration - let _ = response.send(Ok(())); - } - } - } - } - - fn handle_send( - publisher: &iceoryx2::port::publisher::Publisher, - message: UMessage - ) -> Result<(), UStatus> { - let transmission_data = TransmissionData::from_message(&message)?; - - let _header = CustomHeader::from_message(&message)?; - - // Loan sample and write payload - let sample = publisher.loan_uninit() - .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")))?; - - let sample_final = sample.write_payload(transmission_data); - - sample_final.send() - .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to send: {e}")))?; - - Ok(()) - } -} - -#[async_trait] -impl UTransport for Iceoryx2Transport { - async fn send(&self, message: UMessage) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::Send { - message, - response: tx, - }; - - self.command_sender.send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - // Flatten nested Result, _> to Result<(), UStatus> - rx.recv() - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? - } - - async fn register_listener( - &self, - source_filter: &UUri, - sink_filter: Option<&UUri>, - listener: Arc, - ) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::RegisterListener { - source_filter: source_filter.clone(), - sink_filter: sink_filter.cloned(), - response: tx, - }; - - self.command_sender.send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - // Flatten nested Result, _> to Result<(), UStatus> - rx.recv() - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? - } - - async fn unregister_listener( - &self, - source_filter: &UUri, - sink_filter: Option<&UUri>, - listener: Arc, - ) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::UnregisterListener { - source_filter: source_filter.clone(), - sink_filter: sink_filter.cloned(), - response: tx, - }; - - self.command_sender.send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - // Flatten nested Result, _> to Result<(), UStatus> - rx.recv() - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed"))? - } -} - -#[cfg(test)] -mod test; +use async_trait::async_trait; +use iceoryx2::prelude::*; +use std::sync::Arc; +use up_rust::UAttributes; +use up_rust::{UCode, UListener, UMessage, UStatus, UTransport, UUri}; + +mod custom_header; +mod transmission_data; +pub use custom_header::CustomHeader; +pub use transmission_data::TransmissionData; + +use std::collections::HashMap; +use std::future::Future; +use std::pin::Pin; +use std::thread; + +#[derive(Debug)] +enum TransportCommand { + Send { + message: UMessage, + response: std::sync::mpsc::Sender>, + }, + RegisterListener { + source_filter: UUri, + sink_filter: Option, + response: std::sync::mpsc::Sender>, + }, + UnregisterListener { + source_filter: UUri, + sink_filter: Option, + response: std::sync::mpsc::Sender>, + }, +} + +pub struct Iceoryx2Transport { + command_sender: std::sync::mpsc::Sender, +} + +impl Iceoryx2Transport { + pub fn new() -> Result { + let (tx, rx) = std::sync::mpsc::channel(); + + thread::spawn(move || { + Self::background_task(rx); + }); + + Ok(Self { command_sender: tx }) + } + + fn compute_service_name(message: &UMessage) -> Result { + let encode_uri = |uuri: &UUri| Ok::(uuri.to_string()); + + if message.is_publish() { + let source = message + .source() + .ok_or_else(|| UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI"))?; + Ok(format!("up/{}", encode_uri(source)?)) + } else if message.is_request() { + let sink = message + .sink() + .ok_or_else(|| UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI"))?; + Ok(format!("up/{}", encode_uri(sink)?)) + } else if message.is_response() || message.is_notification() { + let source = message + .source() + .ok_or_else(|| UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI"))?; + let sink = message + .sink() + .ok_or_else(|| UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI"))?; + Ok(format!("up/{}/{}", encode_uri(source)?, encode_uri(sink)?)) + } else { + Err(UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + "Unsupported UMessageType", + )) + } + } + + fn background_task(rx: std::sync::mpsc::Receiver) { + let node = match NodeBuilder::new().create::() { + Ok(node) => node, + Err(e) => { + eprintln!("Failed to create iceoryx2 node: {}", e); + return; + } + }; + + let mut publishers: HashMap< + String, + iceoryx2::port::publisher::Publisher, + > = HashMap::new(); + + while let Ok(command) = rx.recv() { + match command { + TransportCommand::Send { message, response } => { + let service_name = match Self::compute_service_name(&message) { + Ok(name) => name, + Err(e) => { + let _ = response.send(Err(e)); + continue; + } + }; + + let publisher = publishers.entry(service_name.clone()).or_insert_with(|| { + let service = node + .service_builder(&service_name.as_str().try_into().unwrap()) + .publish_subscribe::() + .user_header::() + .open_or_create() + .expect("Failed to create service"); + + service + .publisher_builder() + .create() + .expect("Failed to create publisher") + }); + + let result = Self::handle_send(publisher, message); + let _ = response.send(result); + } + TransportCommand::RegisterListener { response, .. } => { + let _ = response.send(Ok(())); // TODO + } + TransportCommand::UnregisterListener { response, .. } => { + let _ = response.send(Ok(())); // TODO + } + } + } + } + + fn handle_send( + publisher: &iceoryx2::port::publisher::Publisher, + message: UMessage + ) -> Result<(), UStatus> { + let transmission_data = TransmissionData::from_message(&message)?; + let header = CustomHeader::from_message(&message)?; + + let sample = publisher.loan_uninit() + .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")))?; + + let mut sample_final = sample.write_payload(transmission_data); + *sample_final.user_header_mut() = header; + + sample_final.send() + .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to send: {e}")))?; + + Ok(()) + } +} + +#[async_trait] +impl UTransport for Iceoryx2Transport { + async fn send(&self, message: UMessage) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::Send { + message, + response: tx, + }; + + self.command_sender + .send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv().map_err(|_| { + UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") + })? + } + + async fn register_listener( + &self, + source_filter: &UUri, + sink_filter: Option<&UUri>, + listener: Arc, + ) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::RegisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + response: tx, + }; + + self.command_sender + .send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv().map_err(|_| { + UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") + })? + } + + async fn unregister_listener( + &self, + source_filter: &UUri, + sink_filter: Option<&UUri>, + listener: Arc, + ) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::UnregisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + response: tx, + }; + + self.command_sender + .send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv().map_err(|_| { + UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") + })? + } +} + +#[cfg(test)] +mod test; diff --git a/src/receiver.rs b/src/receiver.rs index 30cd4d9..dff7f56 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -1,46 +1,46 @@ -use super::*; -use bytes::Bytes; -use std::sync::Arc; - -use async_trait::async_trait; -use up_rust::UAttributes; -use std::sync::Arc; -use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode}; -use iceoryx2::prelude::*; -use tokio::sync::mpsc::UnboundedSender; - - -pub struct Receiver{ - -} - -impl Receiver{ - pub fn new() -> Self{ - Self{ - - } - } -} - -#[async_trait] -impl UListener for Receiver{ - async fn on_receive(&self,message:UMessage)->UStatus{ - if let Some(payload)=message.payload(){ - println!("Receieved Message ID: {}", message.id()); - } - - UStatus::Ok - } -} - -#[tokio::test] -async fn test_receiver(){ - let receiver= Receiver::new(); - let transport = Iceoryx2Transport::new().unwrap(); - source_URI= UUri - sink_filter= - transport.register_listener(receiver).await.unwrap(); - -} - - +use super::*; +use bytes::Bytes; +use std::sync::Arc; + +use async_trait::async_trait; +use up_rust::UAttributes; +use std::sync::Arc; +use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode}; +use iceoryx2::prelude::*; +use tokio::sync::mpsc::UnboundedSender; + + +pub struct Receiver{ + +} + +impl Receiver{ + pub fn new() -> Self{ + Self{ + + } + } +} + +#[async_trait] +impl UListener for Receiver{ + async fn on_receive(&self,message:UMessage)->UStatus{ + if let Some(payload)=message.payload(){ + println!("Receieved Message ID: {}", message.id()); + } + + UStatus::Ok + } +} + +#[tokio::test] +async fn test_receiver(){ + let receiver= Receiver::new(); + let transport = Iceoryx2Transport::new().unwrap(); + source_URI= UUri + sink_filter= + transport.register_listener(receiver).await.unwrap(); + +} + + diff --git a/src/test.rs b/src/test.rs index 8175901..365464f 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,174 +1,189 @@ -use super::*; -use bytes::Bytes; -use std::sync::Arc; - -use protobuf::MessageField; // if you use this in tests - -// Example synchronous test (no async needed) -works -#[test] -fn test_custom_header_from_user_header() { - let header = CustomHeader { version: 2, timestamp: 1000 }; - let new_header = CustomHeader::from_user_header(&header).unwrap(); - assert_eq!(new_header.version, 2); - assert_eq!(new_header.timestamp, 1000); -} - -// Async test requires Tokio runtime - work -#[tokio::test] -async fn test_transport_creation() { - let transport = Iceoryx2Transport::new(); - assert!(transport.is_ok()); -} - -//checks that umessage is correctly parsed into transmission data - works -#[test] -fn test_transmission_data_from_message() { - let data = TransmissionData { - x: 42, - y: -7, - funky: 3.14, - }; - - let bytes = data.to_bytes(); - let mut msg = UMessage::new(); - msg.payload = Some(Bytes::from(bytes)); - - let result = TransmissionData::from_message(&msg); - assert!(result.is_ok()); - let decoded = result.unwrap(); - assert_eq!(decoded.x, 42); - assert_eq!(decoded.y, -7); - assert!((decoded.funky - 3.14).abs() < 1e-6); -} - -//checks that custom header w missing fields works fine - works -#[test] -fn test_custom_header_missing_fields() { - let msg = UMessage::new(); // No attributes set - let result = CustomHeader::from_message(&msg); - assert!(result.is_ok()); // Still shouldn't panic -} - -//checks multiple messages which are sent in sequence - works -#[tokio::test] -async fn test_multiple_sends() { - let transport = Iceoryx2Transport::new().unwrap(); - - for i in 0..5 { - //creating valid transmission data instance - let data = TransmissionData { - x: i, - y: i * 10, - funky: i as f64 + 0.5, - }; - - // convert to bytes - let bytes = data.to_bytes(); - - // wrap in umessage and send - let mut msg = UMessage::new(); - msg.payload = Some(bytes.into()); - - let result = transport.send(msg).await; - - if let Err(e) = &result { - } - - assert!(result.is_ok()); - } -} - -//sending an empty payload - works -#[tokio::test] -async fn test_send_empty_payload() { - let transport = Iceoryx2Transport::new().unwrap(); - - let message = UMessage { - payload: Some(Bytes::from(vec![])), // empty payload - ..Default::default() - }; - - let result = transport.send(message).await; - - // It might be valid or invalid depending on implementation - assert!(result.is_ok() || result.is_err()); -} - -//sending without a payload - works -#[tokio::test] -async fn test_send_no_payload() { - let transport = Iceoryx2Transport::new().unwrap(); - - let message = UMessage::default(); // no payload at all - - let result = transport.send(message).await; - - assert!(result.is_err(), "Expected error when sending without payload"); -} - -//sending a max_sized payload - works -#[tokio::test] -async fn test_send_large_payload() { - let transport = Iceoryx2Transport::new().unwrap(); - - let max_size_payload = vec![0xAB; 1024 * 1024]; // 1MB - let message = UMessage { - payload: Some(Bytes::from(max_size_payload)), - ..Default::default() - }; - - let result = transport.send(message).await; - - assert!(result.is_ok() || result.is_err()); // depends on your transport's buffer limit -} - -//sending multiple concurrent messages - works -#[tokio::test] -async fn test_concurrent_sends() { - let transport = Iceoryx2Transport::new().unwrap(); - let transport = Arc::new(transport); - - let mut handles = vec![]; - - for i in 0..10 { - let transport_clone = Arc::clone(&transport); - handles.push(tokio::spawn(async move { - let data = TransmissionData { - x: i, - y: i * 2, - funky: i as f64 * 1.1, - }; - let mut msg = UMessage::new(); - msg.payload = Some(Bytes::from(data.to_bytes())); - transport_clone.send(msg).await - })); - } - - for handle in handles { - let result = handle.await.unwrap(); - assert!(result.is_ok()); - } -} - - - -#[tokio::test] // works -async fn test_send_message() { - if let Ok(transport) = Iceoryx2Transport::new() { - let uprotocol_header = CustomHeader { - version: 1, - timestamp: 123456789, - }; - - let message = UMessage { - attributes: MessageField::some(UAttributes::from(&uprotocol_header)), - payload: Some(vec![1, 2, 3, 4].into()), - ..Default::default() - }; - - let result = transport.send(message).await; - - // It might fail if no background service is running, so accept Ok or Err. - assert!(result.is_ok() || result.is_err()); - } +use super::*; +use bytes::Bytes; +use std::sync::Arc; +use up_rust::{UMessageBuilder, UPayloadFormat, UUri}; + +use protobuf::MessageField; // if you use this in tests + +// Example synchronous test (no async needed) -works +#[test] +fn test_custom_header_from_user_header() { + let header = CustomHeader { version: 2, timestamp: 1000 }; + let new_header = CustomHeader::from_user_header(&header).unwrap(); + assert_eq!(new_header.version, 2); + assert_eq!(new_header.timestamp, 1000); +} + +// Async test requires Tokio runtime - work +#[tokio::test] +async fn test_transport_creation() { + let transport = Iceoryx2Transport::new(); + assert!(transport.is_ok()); +} + +//checks that umessage is correctly parsed into transmission data - works +#[test] +fn test_transmission_data_from_message() { + let data = TransmissionData { + x: 42, + y: -7, + funky: 3.14, + }; + + let bytes = data.to_bytes(); + let mut msg = UMessage::new(); + msg.payload = Some(Bytes::from(bytes)); + + let result = TransmissionData::from_message(&msg); + assert!(result.is_ok()); + let decoded = result.unwrap(); + assert_eq!(decoded.x, 42); + assert_eq!(decoded.y, -7); + assert!((decoded.funky - 3.14).abs() < 1e-6); +} + +//checks that custom header w missing fields works fine - works +#[test] +fn test_custom_header_missing_fields() { + let msg = UMessage::new(); // No attributes set + let result = CustomHeader::from_message(&msg); + assert!(result.is_ok()); // Still shouldn't panic +} + +//checks multiple messages which are sent in sequence - works +#[tokio::test] +async fn test_multiple_sends() { + let transport = Iceoryx2Transport::new().unwrap(); + + for i in 0..5 { + //creating valid transmission data instance + let data = TransmissionData { + x: i, + y: i * 10, + funky: i as f64 + 0.5, + }; + + // convert to bytes + let bytes = data.to_bytes(); + + // wrap in umessage and send + let authority = format!("sensor{}", i); + let uri = UUri::try_from_parts(&authority, 0xA100, 0x01, 0x8001) + .unwrap_or_else(|e| panic!("Failed to construct URI for '{}': {:?}", authority, e)); + + + let msg = UMessageBuilder::publish(uri) + .build_with_payload(data.to_bytes(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let result = transport.send(msg).await; + + if let Err(e) = &result { + } + + assert!(result.is_ok()); + } +} + +//sending an empty payload - works +#[tokio::test] +async fn test_send_empty_payload() { + let transport = Iceoryx2Transport::new().unwrap(); + + let message = UMessage { + payload: Some(Bytes::from(vec![])), // empty payload + ..Default::default() + }; + + let result = transport.send(message).await; + + // It might be valid or invalid depending on implementation + assert!(result.is_ok() || result.is_err()); +} + +//sending without a payload - works +#[tokio::test] +async fn test_send_no_payload() { + let transport = Iceoryx2Transport::new().unwrap(); + + let message = UMessage::default(); // no payload at all + + let result = transport.send(message).await; + + assert!(result.is_err(), "Expected error when sending without payload"); +} + +//sending a max_sized payload - works +#[tokio::test] +async fn test_send_large_payload() { + let transport = Iceoryx2Transport::new().unwrap(); + + let max_size_payload = vec![0xAB; 1024 * 1024]; // 1MB + let message = UMessage { + payload: Some(Bytes::from(max_size_payload)), + ..Default::default() + }; + + let result = transport.send(message).await; + + assert!(result.is_ok() || result.is_err()); // depends on your transport's buffer limit +} + +//sending multiple concurrent messages - works +#[tokio::test] +async fn test_concurrent_sends() { + let transport = Iceoryx2Transport::new().unwrap(); + let transport = Arc::new(transport); + + let mut handles = vec![]; + + for i in 0..10 { + let transport_clone = Arc::clone(&transport); + handles.push(tokio::spawn(async move { + let data = TransmissionData { + x: i, + y: i * 2, + funky: i as f64 * 1.1, + }; + + let authority = format!("vehicle{}", i); + let uri = UUri::try_from_parts(&authority, 0xA100, 0x01, 0x8001) + .unwrap_or_else(|e| panic!("Failed to construct URI for '{}': {:?}", authority, e)); + + + let msg = UMessageBuilder::publish(uri) + .build_with_payload(data.to_bytes(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + transport_clone.send(msg).await + })); + } + + for handle in handles { + let result = handle.await.unwrap(); + assert!(result.is_ok()); + } +} + + + +#[tokio::test] // works +async fn test_send_message() { + if let Ok(transport) = Iceoryx2Transport::new() { + let uprotocol_header = CustomHeader { + version: 1, + timestamp: 123456789, + }; + + let message = UMessage { + attributes: MessageField::some(UAttributes::from(&uprotocol_header)), + payload: Some(vec![1, 2, 3, 4].into()), + ..Default::default() + }; + + let result = transport.send(message).await; + + // It might fail if no background service is running, so accept Ok or Err. + assert!(result.is_ok() || result.is_err()); + } } \ No newline at end of file diff --git a/src/transmission_data.rs b/src/transmission_data.rs index 9faf8a2..cf82a8f 100644 --- a/src/transmission_data.rs +++ b/src/transmission_data.rs @@ -1,62 +1,62 @@ -// Copyright (c) 2023 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache Software License 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license -// which is available at https://opensource.org/licenses/MIT. -// -// SPDX-License-Identifier: Apache-2.0 OR MIT - -use iceoryx2::prelude::*; -use up_rust::{UMessage, UStatus, UCode}; -use bytes::Bytes; - -#[derive(Debug, Clone, Copy, ZeroCopySend, Default)] -// optional type name; if not set, `core::any::type_name::()` is used -#[type_name("TransmissionData")] -#[repr(C)] -pub struct TransmissionData { - pub x: i32, - pub y: i32, - pub funky: f64, -} - -impl TransmissionData { - pub fn from_bytes(bytes: Vec) -> Result { - if bytes.len() != std::mem::size_of::() { - return Err(UStatus::fail_with_code( - UCode::INVALID_ARGUMENT, - "Invalid byte length for TransmissionData", - )); - } - - let mut data = Self { - x: 0, - y: 0, - funky: 0.0, - }; - let ptr = &mut data as *mut Self as *mut u8; - unsafe { - std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, bytes.len()); - } - Ok(data) - } - - - pub fn to_bytes(&self) -> Vec { - let mut bytes = vec![0u8; std::mem::size_of::()]; - let ptr = self as *const Self as *const u8; - unsafe { - std::ptr::copy_nonoverlapping(ptr, bytes.as_mut_ptr(), bytes.len()); - } - bytes - } - - pub fn from_message(message: &UMessage) -> Result { - let payload = message.payload.clone().unwrap_or_default(); - Self::from_bytes(payload.to_vec()) - } +// Copyright (c) 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use iceoryx2::prelude::*; +use up_rust::{UMessage, UStatus, UCode}; +use bytes::Bytes; + +#[derive(Debug, Clone, Copy, ZeroCopySend, Default)] +// optional type name; if not set, `core::any::type_name::()` is used +#[type_name("TransmissionData")] +#[repr(C)] +pub struct TransmissionData { + pub x: i32, + pub y: i32, + pub funky: f64, +} + +impl TransmissionData { + pub fn from_bytes(bytes: Vec) -> Result { + if bytes.len() != std::mem::size_of::() { + return Err(UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + "Invalid byte length for TransmissionData", + )); + } + + let mut data = Self { + x: 0, + y: 0, + funky: 0.0, + }; + let ptr = &mut data as *mut Self as *mut u8; + unsafe { + std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, bytes.len()); + } + Ok(data) + } + + + pub fn to_bytes(&self) -> Vec { + let mut bytes = vec![0u8; std::mem::size_of::()]; + let ptr = self as *const Self as *const u8; + unsafe { + std::ptr::copy_nonoverlapping(ptr, bytes.as_mut_ptr(), bytes.len()); + } + bytes + } + + pub fn from_message(message: &UMessage) -> Result { + let payload = message.payload.clone().unwrap_or_default(); + Self::from_bytes(payload.to_vec()) + } } \ No newline at end of file From 7c43ba428d210221a5ea3d2e6800809ee96b03fc Mon Sep 17 00:00:00 2001 From: Noella Horo Date: Thu, 3 Jul 2025 03:48:03 +0530 Subject: [PATCH 14/42] modified compute service name to work correctly with the service name type that iceoryx2 expects --- src/lib.rs | 57 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1c4c315..dbead9a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,34 +47,57 @@ impl Iceoryx2Transport { Ok(Self { command_sender: tx }) } + fn encode_uuri_segments(uuri: &UUri) -> Vec { + vec![ + uuri.authority_name.clone(), // assumes already correct + Self::encode_hex_no_leading_zeros(uuri.ue_id), + Self::encode_hex_no_leading_zeros(uuri.ue_version_major), + Self::encode_hex_no_leading_zeros(uuri.resource_id), + ] + } + fn encode_hex_no_leading_zeros(value: u32) -> String { + format!("{:X}", value) + } + + // returns a correct iceoryx2 service name based on the UMessage type + // and its source/sink URIs. fn compute_service_name(message: &UMessage) -> Result { - let encode_uri = |uuri: &UUri| Ok::(uuri.to_string()); + let join_segments = |segments: Vec| segments.join("/"); if message.is_publish() { - let source = message - .source() - .ok_or_else(|| UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI"))?; - Ok(format!("up/{}", encode_uri(source)?)) + let source = message.source().ok_or_else(|| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI") + })?; + let segments = Self::encode_uuri_segments(source); + Ok(format!("up/{}", join_segments(segments))) } else if message.is_request() { - let sink = message - .sink() - .ok_or_else(|| UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI"))?; - Ok(format!("up/{}", encode_uri(sink)?)) + let sink = message.sink().ok_or_else(|| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI") + })?; + let segments = Self::encode_uuri_segments(sink); + Ok(format!("up/{}", join_segments(segments))) } else if message.is_response() || message.is_notification() { - let source = message - .source() - .ok_or_else(|| UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI"))?; - let sink = message - .sink() - .ok_or_else(|| UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI"))?; - Ok(format!("up/{}/{}", encode_uri(source)?, encode_uri(sink)?)) + let source = message.source().ok_or_else(|| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI") + })?; + let sink = message.sink().ok_or_else(|| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI") + })?; + + let source_segments = Self::encode_uuri_segments(source); + let sink_segments = Self::encode_uuri_segments(sink); + Ok(format!( + "up/{}/{}", + join_segments(source_segments), + join_segments(sink_segments) + )) } else { Err(UStatus::fail_with_code( UCode::INVALID_ARGUMENT, "Unsupported UMessageType", )) } - } + } fn background_task(rx: std::sync::mpsc::Receiver) { let node = match NodeBuilder::new().create::() { From b83872b95e645accbd7f4dfaab54a1ec6ff4943f Mon Sep 17 00:00:00 2001 From: Noella Horo Date: Thu, 3 Jul 2025 03:56:59 +0530 Subject: [PATCH 15/42] updated encode uuri segments to handle type and instance from id separately - using availbale helper methods defined in uri.rs --- src/lib.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index dbead9a..862c0d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,16 +49,18 @@ impl Iceoryx2Transport { fn encode_uuri_segments(uuri: &UUri) -> Vec { vec![ - uuri.authority_name.clone(), // assumes already correct - Self::encode_hex_no_leading_zeros(uuri.ue_id), - Self::encode_hex_no_leading_zeros(uuri.ue_version_major), - Self::encode_hex_no_leading_zeros(uuri.resource_id), + uuri.authority_name.clone(), // e.g., "device1" + Self::encode_hex_no_leading_zeros(uuri.uentity_type_id() as u32), + Self::encode_hex_no_leading_zeros(uuri.uentity_instance_id() as u32), + Self::encode_hex_no_leading_zeros(uuri.uentity_major_version() as u32), + Self::encode_hex_no_leading_zeros(uuri.resource_id() as u32), ] } + fn encode_hex_no_leading_zeros(value: u32) -> String { format!("{:X}", value) - } - + } + // returns a correct iceoryx2 service name based on the UMessage type // and its source/sink URIs. fn compute_service_name(message: &UMessage) -> Result { @@ -97,7 +99,7 @@ impl Iceoryx2Transport { "Unsupported UMessageType", )) } - } + } fn background_task(rx: std::sync::mpsc::Receiver) { let node = match NodeBuilder::new().create::() { From a77699f2ccab7539711b833c454aa046723554fb Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Thu, 3 Jul 2025 05:44:41 +0530 Subject: [PATCH 16/42] receiver.rs detected by cargo test --- Cargo.lock | 166 ++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 + src/lib.rs | 1 + src/receiver.rs | 27 +++++--- src/test.rs | 5 +- 5 files changed, 191 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19a347c..bba27da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,12 +26,56 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + [[package]] name = "anstyle" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.59.0", +] + [[package]] name = "anyhow" version = "1.0.98" @@ -156,6 +200,12 @@ dependencies = [ "libloading", ] +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "downcast" version = "0.11.0" @@ -188,6 +238,29 @@ dependencies = [ "syn", ] +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -466,6 +539,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.12.1" @@ -475,6 +554,30 @@ dependencies = [ "either", ] +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -620,6 +723,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "outref" version = "0.5.2" @@ -655,6 +764,21 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1051,6 +1175,39 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" +[[package]] +name = "test-case" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" +dependencies = [ + "test-case-macros", +] + +[[package]] +name = "test-case-core" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "test-case-macros" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "test-case-core", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -1200,8 +1357,11 @@ version = "0.1.0" dependencies = [ "async-trait", "bytes", + "env_logger", "iceoryx2", + "log", "protobuf", + "test-case", "tokio", "up-rust", ] @@ -1216,6 +1376,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid-simd" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 338d727..4e0dc9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,9 @@ async-trait = "0.1" protobuf = "3.7.2" bytes = "1.10.1" tokio = { version = "1", features = ["full"] } +test-case = "3" +log = "0.4.27" +env_logger = "0.11.8" [dev-dependencies] up-rust = { version = "0.5.0", features = ["test-util"] } diff --git a/src/lib.rs b/src/lib.rs index e444535..f9bb173 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -182,3 +182,4 @@ impl UTransport for Iceoryx2Transport { #[cfg(test)] mod test; +mod receiver; diff --git a/src/receiver.rs b/src/receiver.rs index 81a8364..4aba478 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -1,13 +1,21 @@ use super::*; -use bytes::Bytes; use std::sync::Arc; +use std::time::Duration; use async_trait::async_trait; -use up_rust::UAttributes; -use std::sync::Arc; -use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode}; +use bytes::Bytes; +use tokio::sync::Notify; +use log::info; + +use up_rust::{ + UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, + UStatus, UTransport, UUri, +}; +use std::str::FromStr; use iceoryx2::prelude::*; -use tokio::sync::mpsc::UnboundedSender; +use env_logger; + + const MESSAGE_DATA: &str = "Hello World!"; @@ -25,14 +33,12 @@ impl Receiver{ #[async_trait] impl UListener for Receiver{ - async fn on_receive(&self,message:UMessage)->UStatus{ - if let Some(payload)=message.payload(){ - println!("Receieved Message ID: {}", message.id()); + async fn on_receive(&self,message:UMessage)->(){ + if let Some(payload)=&message.payload{ + println!("Receieved Message ID: {:#?}", message.id()); assert_eq!(self.expected, message); self.notify.notify_one(); } - - UStatus::Ok } } @@ -42,6 +48,7 @@ async fn register_listener_and_send( source_filter: &UUri, sink_filter: Option<&UUri>, ) -> Result<(), Box> { + env_logger::init(); let source_uri= UUri::try_from_parts(authority, 0xABC, 1, 0)?; let transport = Iceoryx2Transport::new().unwrap(); let notify = Arc::new(Notify::new()); diff --git a/src/test.rs b/src/test.rs index 8175901..8fcea23 100644 --- a/src/test.rs +++ b/src/test.rs @@ -171,4 +171,7 @@ async fn test_send_message() { // It might fail if no background service is running, so accept Ok or Err. assert!(result.is_ok() || result.is_err()); } -} \ No newline at end of file +} + + + \ No newline at end of file From 94ce30074739769b6909eec503d33e73e5df9a6b Mon Sep 17 00:00:00 2001 From: Noella Horo Date: Thu, 3 Jul 2025 06:09:54 +0530 Subject: [PATCH 17/42] test cases to verify conversion from uri to iceoryx2 addressing scheme (iceoryx2 definition for service name) --- Cargo.lock | 3064 ++++++++++++++++++++++++++-------------------------- src/lib.rs | 94 +- 2 files changed, 1625 insertions(+), 1533 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5bdade1..19a347c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,1532 +1,1532 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstyle" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" - -[[package]] -name = "anyhow" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" - -[[package]] -name = "async-trait" -version = "0.1.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", - "which", -] - -[[package]] -name = "bitflags" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "cc" -version = "1.2.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" -dependencies = [ - "shlex", -] - -[[package]] -name = "cdr" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9617422bf43fde9280707a7e90f8f7494389c182f5c70b0f67592d0f06d41dfa" -dependencies = [ - "byteorder", - "serde", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "downcast" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "enum-iterator" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635" -dependencies = [ - "enum-iterator-derive", -] - -[[package]] -name = "enum-iterator-derive" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "fragile" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - -[[package]] -name = "hashbrown" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" - -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "iceoryx2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a462c1baccde41be91001f7b36cb1d1afe313c2afdb5a6c16174ae7ca917b6ef" -dependencies = [ - "iceoryx2-bb-container", - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-lock-free", - "iceoryx2-bb-log", - "iceoryx2-bb-memory", - "iceoryx2-bb-posix", - "iceoryx2-bb-system-types", - "iceoryx2-cal", - "iceoryx2-pal-concurrency-sync", - "serde", - "tiny-fn", - "toml", -] - -[[package]] -name = "iceoryx2-bb-container" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6205871fd23e67215ec4dff6b9895f7526325b498b2eb759b93399ee69d6d89" -dependencies = [ - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-log", - "iceoryx2-pal-concurrency-sync", - "serde", -] - -[[package]] -name = "iceoryx2-bb-derive-macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "468faacface5d0252a090d565d9da86c05dc77e822abebdc0affeaad9021cce6" -dependencies = [ - "iceoryx2-bb-elementary", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "iceoryx2-bb-elementary" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af6479bb3aed7cfb398e54e91a769629d64f5bc2ede8c6a528ee02daa1675a5" -dependencies = [ - "iceoryx2-bb-elementary-traits", - "iceoryx2-pal-concurrency-sync", -] - -[[package]] -name = "iceoryx2-bb-elementary-traits" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb55d8c8b866531332904fd5a7041355d67d91d722f2e22850c1364ca779d30" -dependencies = [ - "iceoryx2-pal-concurrency-sync", -] - -[[package]] -name = "iceoryx2-bb-lock-free" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9e850529efc04e4f70789fc8a8016883cda0ee9b88a078f0b6d296cc966b11" -dependencies = [ - "iceoryx2-bb-elementary", - "iceoryx2-bb-log", - "iceoryx2-pal-concurrency-sync", -] - -[[package]] -name = "iceoryx2-bb-log" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54d933cadfd6ac326dbce588fa5e1203b1b85234899a1742ad16a64490631dd" -dependencies = [ - "iceoryx2-pal-concurrency-sync", - "termsize", -] - -[[package]] -name = "iceoryx2-bb-memory" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b03e120e45d869979da01f894c226ed24c49feb3a318acbb7106021962d205" -dependencies = [ - "iceoryx2-bb-elementary", - "iceoryx2-bb-lock-free", - "iceoryx2-bb-log", - "iceoryx2-bb-posix", - "iceoryx2-pal-concurrency-sync", -] - -[[package]] -name = "iceoryx2-bb-posix" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc53c019df6e0aa5df7bf8052cc11064a4ba19fe7bc34671f8ce13c2eb7ac3ab" -dependencies = [ - "enum-iterator", - "iceoryx2-bb-container", - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-log", - "iceoryx2-bb-system-types", - "iceoryx2-pal-concurrency-sync", - "iceoryx2-pal-configuration", - "iceoryx2-pal-posix", - "lazy_static", - "serde", - "tiny-fn", -] - -[[package]] -name = "iceoryx2-bb-system-types" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346e9593393627c2cbc17b8663a0650c8e33377276f2e06e10346816705ae5cb" -dependencies = [ - "iceoryx2-bb-container", - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-log", - "iceoryx2-pal-configuration", - "iceoryx2-pal-posix", - "serde", -] - -[[package]] -name = "iceoryx2-cal" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9941d8beb989b80b581d2a6871e4b464b695bc1f86076117be1eb9c74f3dcb" -dependencies = [ - "cdr", - "iceoryx2-bb-container", - "iceoryx2-bb-derive-macros", - "iceoryx2-bb-elementary", - "iceoryx2-bb-lock-free", - "iceoryx2-bb-log", - "iceoryx2-bb-memory", - "iceoryx2-bb-posix", - "iceoryx2-bb-system-types", - "iceoryx2-pal-concurrency-sync", - "once_cell", - "serde", - "sha1_smol", - "tiny-fn", - "toml", -] - -[[package]] -name = "iceoryx2-pal-concurrency-sync" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bc07c3be1bce2afef70dc5597abe14bdadde367f759243e92325a96733163d6" - -[[package]] -name = "iceoryx2-pal-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a94e78e84f673da8ee4b46cb5df643792b046b7118678da9969fee29cf15c68" - -[[package]] -name = "iceoryx2-pal-posix" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5616e41d3171df75d1ab9577d5bccdc4fb95102e275db2afd84a9828a0a01918" -dependencies = [ - "bindgen", - "cc", - "iceoryx2-pal-concurrency-sync", - "iceoryx2-pal-configuration", - "lazy_static", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "indexmap" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.0", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "lock_api" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "mediatype" -version = "0.19.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33746aadcb41349ec291e7f2f0a3aa6834d1d7c58066fb4b01f68efc4c4b7631" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" -dependencies = [ - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] - -[[package]] -name = "mockall" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "mockall_derive", - "predicates", - "predicates-tree", -] - -[[package]] -name = "mockall_derive" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "outref" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" - -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "predicates" -version = "3.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" -dependencies = [ - "anstyle", - "predicates-core", -] - -[[package]] -name = "predicates-core" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" - -[[package]] -name = "predicates-tree" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" -dependencies = [ - "predicates-core", - "termtree", -] - -[[package]] -name = "prettyplease" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "protobuf" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" -dependencies = [ - "bytes", - "once_cell", - "protobuf-support", - "thiserror", -] - -[[package]] -name = "protobuf-codegen" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3976825c0014bbd2f3b34f0001876604fe87e0c86cd8fa54251530f1544ace" -dependencies = [ - "anyhow", - "once_cell", - "protobuf", - "protobuf-parse", - "regex", - "tempfile", - "thiserror", -] - -[[package]] -name = "protobuf-parse" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" -dependencies = [ - "anyhow", - "indexmap", - "log", - "protobuf", - "protobuf-support", - "tempfile", - "thiserror", - "which", -] - -[[package]] -name = "protobuf-support" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" -dependencies = [ - "thiserror", -] - -[[package]] -name = "protoc-bin-vendored" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd89a830d0eab2502c81a9b8226d446a52998bb78e5e33cb2637c0cdd6068d99" -dependencies = [ - "protoc-bin-vendored-linux-aarch_64", - "protoc-bin-vendored-linux-ppcle_64", - "protoc-bin-vendored-linux-x86_32", - "protoc-bin-vendored-linux-x86_64", - "protoc-bin-vendored-macos-aarch_64", - "protoc-bin-vendored-macos-x86_64", - "protoc-bin-vendored-win32", -] - -[[package]] -name = "protoc-bin-vendored-linux-aarch_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f563627339f1653ea1453dfbcb4398a7369b768925eb14499457aeaa45afe22c" - -[[package]] -name = "protoc-bin-vendored-linux-ppcle_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5025c949a02cd3b60c02501dd0f348c16e8fff464f2a7f27db8a9732c608b746" - -[[package]] -name = "protoc-bin-vendored-linux-x86_32" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9500ce67d132c2f3b572504088712db715755eb9adf69d55641caa2cb68a07" - -[[package]] -name = "protoc-bin-vendored-linux-x86_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5462592380cefdc9f1f14635bcce70ba9c91c1c2464c7feb2ce564726614cc41" - -[[package]] -name = "protoc-bin-vendored-macos-aarch_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c637745681b68b4435484543667a37606c95ddacf15e917710801a0877506030" - -[[package]] -name = "protoc-bin-vendored-macos-x86_64" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38943f3c90319d522f94a6dfd4a134ba5e36148b9506d2d9723a82ebc57c8b55" - -[[package]] -name = "protoc-bin-vendored-win32" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc55d7dec32ecaf61e0bd90b3d2392d721a28b95cfd23c3e176eccefbeab2f2" - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "redox_syscall" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" -dependencies = [ - "libc", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "syn" -version = "2.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix 1.0.7", - "windows-sys 0.59.0", -] - -[[package]] -name = "termsize" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f11ff5c25c172608d5b85e2fb43ee9a6d683a7f4ab7f96ae07b3d8b590368fd" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "termtree" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tiny-fn" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fde9a76dac5751480f711f327371c809d7f8a9f036436e6237d67859adbf3bd" - -[[package]] -name = "tokio" -version = "1.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-macros" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "log", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "up-rust" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616da735a2c488128e67d5ce16113f4303c83a5dbeb7c281ae893da281df2a57" -dependencies = [ - "async-trait", - "bytes", - "mediatype", - "mockall", - "protobuf", - "protobuf-codegen", - "protoc-bin-vendored", - "rand", - "thiserror", - "tokio", - "tracing", - "uriparse", - "uuid-simd", -] - -[[package]] -name = "up-transport-iceoryx2-rust" -version = "0.1.0" -dependencies = [ - "async-trait", - "bytes", - "iceoryx2", - "protobuf", - "tokio", - "up-rust", -] - -[[package]] -name = "uriparse" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" -dependencies = [ - "fnv", - "lazy_static", -] - -[[package]] -name = "uuid-simd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" -dependencies = [ - "outref", - "vsimd", -] - -[[package]] -name = "vsimd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" -dependencies = [ - "wit-bindgen-rt", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "winnow" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] - -[[package]] -name = "zerocopy" -version = "0.8.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" +dependencies = [ + "shlex", +] + +[[package]] +name = "cdr" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9617422bf43fde9280707a7e90f8f7494389c182f5c70b0f67592d0f06d41dfa" +dependencies = [ + "byteorder", + "serde", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "enum-iterator" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fragile" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "iceoryx2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a462c1baccde41be91001f7b36cb1d1afe313c2afdb5a6c16174ae7ca917b6ef" +dependencies = [ + "iceoryx2-bb-container", + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-lock-free", + "iceoryx2-bb-log", + "iceoryx2-bb-memory", + "iceoryx2-bb-posix", + "iceoryx2-bb-system-types", + "iceoryx2-cal", + "iceoryx2-pal-concurrency-sync", + "serde", + "tiny-fn", + "toml", +] + +[[package]] +name = "iceoryx2-bb-container" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6205871fd23e67215ec4dff6b9895f7526325b498b2eb759b93399ee69d6d89" +dependencies = [ + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", + "iceoryx2-pal-concurrency-sync", + "serde", +] + +[[package]] +name = "iceoryx2-bb-derive-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468faacface5d0252a090d565d9da86c05dc77e822abebdc0affeaad9021cce6" +dependencies = [ + "iceoryx2-bb-elementary", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "iceoryx2-bb-elementary" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af6479bb3aed7cfb398e54e91a769629d64f5bc2ede8c6a528ee02daa1675a5" +dependencies = [ + "iceoryx2-bb-elementary-traits", + "iceoryx2-pal-concurrency-sync", +] + +[[package]] +name = "iceoryx2-bb-elementary-traits" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb55d8c8b866531332904fd5a7041355d67d91d722f2e22850c1364ca779d30" +dependencies = [ + "iceoryx2-pal-concurrency-sync", +] + +[[package]] +name = "iceoryx2-bb-lock-free" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9e850529efc04e4f70789fc8a8016883cda0ee9b88a078f0b6d296cc966b11" +dependencies = [ + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", + "iceoryx2-pal-concurrency-sync", +] + +[[package]] +name = "iceoryx2-bb-log" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54d933cadfd6ac326dbce588fa5e1203b1b85234899a1742ad16a64490631dd" +dependencies = [ + "iceoryx2-pal-concurrency-sync", + "termsize", +] + +[[package]] +name = "iceoryx2-bb-memory" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45b03e120e45d869979da01f894c226ed24c49feb3a318acbb7106021962d205" +dependencies = [ + "iceoryx2-bb-elementary", + "iceoryx2-bb-lock-free", + "iceoryx2-bb-log", + "iceoryx2-bb-posix", + "iceoryx2-pal-concurrency-sync", +] + +[[package]] +name = "iceoryx2-bb-posix" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc53c019df6e0aa5df7bf8052cc11064a4ba19fe7bc34671f8ce13c2eb7ac3ab" +dependencies = [ + "enum-iterator", + "iceoryx2-bb-container", + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", + "iceoryx2-bb-system-types", + "iceoryx2-pal-concurrency-sync", + "iceoryx2-pal-configuration", + "iceoryx2-pal-posix", + "lazy_static", + "serde", + "tiny-fn", +] + +[[package]] +name = "iceoryx2-bb-system-types" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346e9593393627c2cbc17b8663a0650c8e33377276f2e06e10346816705ae5cb" +dependencies = [ + "iceoryx2-bb-container", + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", + "iceoryx2-pal-configuration", + "iceoryx2-pal-posix", + "serde", +] + +[[package]] +name = "iceoryx2-cal" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9941d8beb989b80b581d2a6871e4b464b695bc1f86076117be1eb9c74f3dcb" +dependencies = [ + "cdr", + "iceoryx2-bb-container", + "iceoryx2-bb-derive-macros", + "iceoryx2-bb-elementary", + "iceoryx2-bb-lock-free", + "iceoryx2-bb-log", + "iceoryx2-bb-memory", + "iceoryx2-bb-posix", + "iceoryx2-bb-system-types", + "iceoryx2-pal-concurrency-sync", + "once_cell", + "serde", + "sha1_smol", + "tiny-fn", + "toml", +] + +[[package]] +name = "iceoryx2-pal-concurrency-sync" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bc07c3be1bce2afef70dc5597abe14bdadde367f759243e92325a96733163d6" + +[[package]] +name = "iceoryx2-pal-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a94e78e84f673da8ee4b46cb5df643792b046b7118678da9969fee29cf15c68" + +[[package]] +name = "iceoryx2-pal-posix" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5616e41d3171df75d1ab9577d5bccdc4fb95102e275db2afd84a9828a0a01918" +dependencies = [ + "bindgen", + "cc", + "iceoryx2-pal-concurrency-sync", + "iceoryx2-pal-configuration", + "lazy_static", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.0", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "mediatype" +version = "0.19.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33746aadcb41349ec291e7f2f0a3aa6834d1d7c58066fb4b01f68efc4c4b7631" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "mockall" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "predicates" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +dependencies = [ + "anstyle", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" + +[[package]] +name = "predicates-tree" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "prettyplease" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protobuf" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" +dependencies = [ + "bytes", + "once_cell", + "protobuf-support", + "thiserror", +] + +[[package]] +name = "protobuf-codegen" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3976825c0014bbd2f3b34f0001876604fe87e0c86cd8fa54251530f1544ace" +dependencies = [ + "anyhow", + "once_cell", + "protobuf", + "protobuf-parse", + "regex", + "tempfile", + "thiserror", +] + +[[package]] +name = "protobuf-parse" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" +dependencies = [ + "anyhow", + "indexmap", + "log", + "protobuf", + "protobuf-support", + "tempfile", + "thiserror", + "which", +] + +[[package]] +name = "protobuf-support" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" +dependencies = [ + "thiserror", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd89a830d0eab2502c81a9b8226d446a52998bb78e5e33cb2637c0cdd6068d99" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-aarch_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f563627339f1653ea1453dfbcb4398a7369b768925eb14499457aeaa45afe22c" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5025c949a02cd3b60c02501dd0f348c16e8fff464f2a7f27db8a9732c608b746" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9500ce67d132c2f3b572504088712db715755eb9adf69d55641caa2cb68a07" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5462592380cefdc9f1f14635bcce70ba9c91c1c2464c7feb2ce564726614cc41" + +[[package]] +name = "protoc-bin-vendored-macos-aarch_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c637745681b68b4435484543667a37606c95ddacf15e917710801a0877506030" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38943f3c90319d522f94a6dfd4a134ba5e36148b9506d2d9723a82ebc57c8b55" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dc55d7dec32ecaf61e0bd90b3d2392d721a28b95cfd23c3e176eccefbeab2f2" + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "redox_syscall" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "syn" +version = "2.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.0.7", + "windows-sys 0.59.0", +] + +[[package]] +name = "termsize" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f11ff5c25c172608d5b85e2fb43ee9a6d683a7f4ab7f96ae07b3d8b590368fd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiny-fn" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fde9a76dac5751480f711f327371c809d7f8a9f036436e6237d67859adbf3bd" + +[[package]] +name = "tokio" +version = "1.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "up-rust" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616da735a2c488128e67d5ce16113f4303c83a5dbeb7c281ae893da281df2a57" +dependencies = [ + "async-trait", + "bytes", + "mediatype", + "mockall", + "protobuf", + "protobuf-codegen", + "protoc-bin-vendored", + "rand", + "thiserror", + "tokio", + "tracing", + "uriparse", + "uuid-simd", +] + +[[package]] +name = "up-transport-iceoryx2-rust" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "iceoryx2", + "protobuf", + "tokio", + "up-rust", +] + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "uuid-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" +dependencies = [ + "outref", + "vsimd", +] + +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/src/lib.rs b/src/lib.rs index 862c0d1..787a8ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -239,5 +239,97 @@ impl UTransport for Iceoryx2Transport { } } +fn test_uri(authority: &str, instance: u16, typ: u16, version: u8, resource: u16) -> UUri { + let entity_id = ((instance as u32) << 16) | (typ as u32); + UUri::try_from_parts(authority, entity_id, version, resource).unwrap() +} + #[cfg(test)] -mod test; +mod tests { + use super::*; + use up_rust::{UPayloadFormat, UStatus, UMessageBuilder}; + + use up_rust::UUID; + use std::convert::TryFrom; + + // fn dummy_uuid() -> up_rust::UUID { + // // let uuid = UUID::new(); + // let uuid = up_rust::UUID::new(); + // up_rust::UUID::try_from(uuid).expect("Valid UUID conversion") + // } + fn dummy_uuid() -> up_rust::UUID { + up_rust::UUID::build() + } + + // Helper function to create a test URI + fn test_uri(authority: &str, instance: u16, typ: u16, version: u8, resource: u16) -> UUri { + let entity_id = ((instance as u32) << 16) | (typ as u32); + UUri::try_from_parts(authority, entity_id, version, resource).unwrap() + } + + #[test] + fn test_publish_service_name() { + let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); + let message = UMessageBuilder::publish(source.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/10AB/0/3/80CD"); + } + + #[test] + fn test_notification_service_name() { + let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); + let sink = test_uri("device1", 0x0000, 0x30EF, 0x04, 0x0000); + let message = UMessageBuilder::notification(source.clone(), sink.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/10AB/0/3/80CD/device1/30EF/0/4/0"); + } + + #[test] + fn test_rpc_request_service_name() { + let sink = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); + let reply_to = test_uri("device1", 0x0000, 0x0001, 0x01, 0x0000); // Dummy reply URI + + let message = UMessageBuilder::request(sink.clone(), reply_to, 1000) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/CD/0/4/B"); + } + + + #[test] + fn test_rpc_response_service_name() { + let source = test_uri("device1", 0x0001, 0x0020, 0x01, 0x0000); + let sink = test_uri("device1", 0x0001, 0x00CD, 0x04, 0x1000); + let uuid = dummy_uuid(); + + let message = UMessageBuilder::response(source.clone(), uuid, sink.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + + assert_eq!( + name, + "up/device1/CD/1/4/1000/device1/20/1/1/0" + ); + } + + + + #[test] + fn test_missing_uri_error() { + let message = UMessage::new(); // no source or sink + let result = Iceoryx2Transport::compute_service_name(&message); + + assert!(result.is_err()); + assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); + } +} From 32afab337fbf03d23a34c78e39f232865dbdae12 Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:20:17 +0530 Subject: [PATCH 18/42] fixed logger error --- src/receiver.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/receiver.rs b/src/receiver.rs index 4aba478..7e8911d 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -15,6 +15,16 @@ use std::str::FromStr; use iceoryx2::prelude::*; use env_logger; +use std::sync::Once; + +static INIT_LOGGER: Once = Once::new(); + +fn init_logger() { + INIT_LOGGER.call_once(|| { + env_logger::init(); + }); +} + const MESSAGE_DATA: &str = "Hello World!"; @@ -48,7 +58,7 @@ async fn register_listener_and_send( source_filter: &UUri, sink_filter: Option<&UUri>, ) -> Result<(), Box> { - env_logger::init(); + init_logger(); let source_uri= UUri::try_from_parts(authority, 0xABC, 1, 0)?; let transport = Iceoryx2Transport::new().unwrap(); let notify = Arc::new(Notify::new()); From 86439c6672c6f048abe3d03463e756fbe90f8746 Mon Sep 17 00:00:00 2001 From: arakabCL Date: Thu, 3 Jul 2025 13:08:04 -0400 Subject: [PATCH 19/42] feat: Implement listener registration and unregistration This commit introduces the and functionalities for the . Key changes include: - Implemented the method to allow clients to subscribe to uProtocol messages. - Implemented the method to allow clients to unsubscribe. - Added tests for both registration and unregistration. --- .DS_Store | Bin 0 -> 6148 bytes src/bin/sender.rs | 39 ++ src/custom_header.rs | 111 ++--- src/lib.rs | 943 +++++++++++++++++++++++++-------------- src/receiver.rs | 32 +- src/test.rs | 189 -------- src/transmission_data.rs | 122 +++-- 7 files changed, 779 insertions(+), 657 deletions(-) create mode 100644 .DS_Store create mode 100644 src/bin/sender.rs delete mode 100644 src/test.rs diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6d6450171ab05407b5386718b108c3a4bfc1f1ce GIT binary patch literal 6148 zcmeHKJ8DBQ5S)!oFr;yrQdh_ggmF%g3nZ~k8iOHr`d9f}Ia+2v1e?c$G-=E%tVUYx zNN9?;ZvoiqYx@K&0W9c_IQuX*-*+F`T}2$t&)DqW4~IRcxF01?1e`m=5uey>kC*%t z-WdGA4yVhFiDML&0#ZN t, + Err(e) => { + eprintln!("Failed to create transport: {:?}", e); + return; + } + }; + + // Define a topic URI to publish to + let source_uri = UUri::try_from_parts("vehicle", 0x1000, 1, 0x8001).unwrap(); + + // Create a sample payload + let data = TransmissionData { + x: 123, + y: 456, + funky: 9.87, + }; + let payload_bytes = data.to_bytes(); + + // Build the UMessage + let msg = UMessageBuilder::publish(source_uri.clone()) + .build_with_payload(payload_bytes, UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .expect("Failed to build message"); + + println!("Sending message to URI: {}", source_uri); + + // Send the message + match transport.send(msg).await { + Ok(_) => println!("Message sent successfully!"), + Err(e) => eprintln!("Failed to send message: {:?}", e), + } +} diff --git a/src/custom_header.rs b/src/custom_header.rs index 9f8d1fb..ac0f168 100644 --- a/src/custom_header.rs +++ b/src/custom_header.rs @@ -1,54 +1,57 @@ -use iceoryx2::prelude::*; -use up_rust::{UMessage, UStatus, UCode, UAttributes}; - -#[derive(Default, Debug, ZeroCopySend)] -#[type_name("CustomHeader")] -#[repr(C)] -pub struct CustomHeader { - pub version: i32, - pub timestamp: u64, -} - -impl CustomHeader { - pub fn from_user_header(header: &Self) -> Result { - Ok(Self { - version: header.version, - timestamp: header.timestamp, - }) - } - - pub fn from_message(_message: &UMessage) -> Result { - // For now, just default - Ok(Self::default()) - } -} - -// Assuming UAttributes has a field called `fields` which is Vec<(String, String)> -// Adjust if your actual UAttributes is different -impl From<&CustomHeader> for UAttributes { - fn from(_header: &CustomHeader) -> UAttributes { - let attrs = UAttributes::default(); - - // Hypothetical code: add key-value pairs to attrs - // Replace this with your real API to insert attributes - // For example, if UAttributes has a `fields` Vec<(String, String)>: - // attrs.fields.push(("version".to_string(), header.version.to_string())); - // attrs.fields.push(("timestamp".to_string(), header.timestamp.to_string())); - - // If no such field exists, just return default or implement accordingly - - attrs - } -} - -#[cfg(test)] -mod tests{ -use super::*; -#[test] -fn test_custom_header_from_user_header() { - let header = CustomHeader { version: 2, timestamp: 1000 }; - let new_header = CustomHeader::from_user_header(&header).unwrap(); - assert_eq!(new_header.version, 2); - assert_eq!(new_header.timestamp, 1000); -} -} \ No newline at end of file +use iceoryx2::prelude::*; +use up_rust::{UAttributes, UMessage, UStatus}; + +#[derive(Default, Debug, ZeroCopySend)] +#[type_name("CustomHeader")] +#[repr(C)] +pub struct CustomHeader { + pub version: i32, + pub timestamp: u64, +} + +impl CustomHeader { + pub fn from_user_header(header: &Self) -> Result { + Ok(Self { + version: header.version, + timestamp: header.timestamp, + }) + } + + pub fn from_message(_message: &UMessage) -> Result { + // For now, just default + Ok(Self::default()) + } +} + +// Assuming UAttributes has a field called `fields` which is Vec<(String, String)> +// Adjust if your actual UAttributes is different +impl From<&CustomHeader> for UAttributes { + fn from(_header: &CustomHeader) -> UAttributes { + let attrs = UAttributes::default(); + + // Hypothetical code: add key-value pairs to attrs + // Replace this with your real API to insert attributes + // For example, if UAttributes has a `fields` Vec<(String, String)>: + // attrs.fields.push(("version".to_string(), header.version.to_string())); + // attrs.fields.push(("timestamp".to_string(), header.timestamp.to_string())); + + // If no such field exists, just return default or implement accordingly + + attrs + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_custom_header_from_user_header() { + let header = CustomHeader { + version: 2, + timestamp: 1000, + }; + let new_header = CustomHeader::from_user_header(&header).unwrap(); + assert_eq!(new_header.version, 2); + assert_eq!(new_header.timestamp, 1000); + } +} diff --git a/src/lib.rs b/src/lib.rs index 787a8ba..7ef8896 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,335 +1,608 @@ -use async_trait::async_trait; -use iceoryx2::prelude::*; -use std::sync::Arc; -use up_rust::UAttributes; -use up_rust::{UCode, UListener, UMessage, UStatus, UTransport, UUri}; - -mod custom_header; -mod transmission_data; -pub use custom_header::CustomHeader; -pub use transmission_data::TransmissionData; - -use std::collections::HashMap; -use std::future::Future; -use std::pin::Pin; -use std::thread; - -#[derive(Debug)] -enum TransportCommand { - Send { - message: UMessage, - response: std::sync::mpsc::Sender>, - }, - RegisterListener { - source_filter: UUri, - sink_filter: Option, - response: std::sync::mpsc::Sender>, - }, - UnregisterListener { - source_filter: UUri, - sink_filter: Option, - response: std::sync::mpsc::Sender>, - }, -} - -pub struct Iceoryx2Transport { - command_sender: std::sync::mpsc::Sender, -} - -impl Iceoryx2Transport { - pub fn new() -> Result { - let (tx, rx) = std::sync::mpsc::channel(); - - thread::spawn(move || { - Self::background_task(rx); - }); - - Ok(Self { command_sender: tx }) - } - - fn encode_uuri_segments(uuri: &UUri) -> Vec { - vec![ - uuri.authority_name.clone(), // e.g., "device1" - Self::encode_hex_no_leading_zeros(uuri.uentity_type_id() as u32), - Self::encode_hex_no_leading_zeros(uuri.uentity_instance_id() as u32), - Self::encode_hex_no_leading_zeros(uuri.uentity_major_version() as u32), - Self::encode_hex_no_leading_zeros(uuri.resource_id() as u32), - ] - } - - fn encode_hex_no_leading_zeros(value: u32) -> String { - format!("{:X}", value) - } - - // returns a correct iceoryx2 service name based on the UMessage type - // and its source/sink URIs. - fn compute_service_name(message: &UMessage) -> Result { - let join_segments = |segments: Vec| segments.join("/"); - - if message.is_publish() { - let source = message.source().ok_or_else(|| { - UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI") - })?; - let segments = Self::encode_uuri_segments(source); - Ok(format!("up/{}", join_segments(segments))) - } else if message.is_request() { - let sink = message.sink().ok_or_else(|| { - UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI") - })?; - let segments = Self::encode_uuri_segments(sink); - Ok(format!("up/{}", join_segments(segments))) - } else if message.is_response() || message.is_notification() { - let source = message.source().ok_or_else(|| { - UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI") - })?; - let sink = message.sink().ok_or_else(|| { - UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI") - })?; - - let source_segments = Self::encode_uuri_segments(source); - let sink_segments = Self::encode_uuri_segments(sink); - Ok(format!( - "up/{}/{}", - join_segments(source_segments), - join_segments(sink_segments) - )) - } else { - Err(UStatus::fail_with_code( - UCode::INVALID_ARGUMENT, - "Unsupported UMessageType", - )) - } - } - - fn background_task(rx: std::sync::mpsc::Receiver) { - let node = match NodeBuilder::new().create::() { - Ok(node) => node, - Err(e) => { - eprintln!("Failed to create iceoryx2 node: {}", e); - return; - } - }; - - let mut publishers: HashMap< - String, - iceoryx2::port::publisher::Publisher, - > = HashMap::new(); - - while let Ok(command) = rx.recv() { - match command { - TransportCommand::Send { message, response } => { - let service_name = match Self::compute_service_name(&message) { - Ok(name) => name, - Err(e) => { - let _ = response.send(Err(e)); - continue; - } - }; - - let publisher = publishers.entry(service_name.clone()).or_insert_with(|| { - let service = node - .service_builder(&service_name.as_str().try_into().unwrap()) - .publish_subscribe::() - .user_header::() - .open_or_create() - .expect("Failed to create service"); - - service - .publisher_builder() - .create() - .expect("Failed to create publisher") - }); - - let result = Self::handle_send(publisher, message); - let _ = response.send(result); - } - TransportCommand::RegisterListener { response, .. } => { - let _ = response.send(Ok(())); // TODO - } - TransportCommand::UnregisterListener { response, .. } => { - let _ = response.send(Ok(())); // TODO - } - } - } - } - - fn handle_send( - publisher: &iceoryx2::port::publisher::Publisher, - message: UMessage - ) -> Result<(), UStatus> { - let transmission_data = TransmissionData::from_message(&message)?; - let header = CustomHeader::from_message(&message)?; - - let sample = publisher.loan_uninit() - .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")))?; - - let mut sample_final = sample.write_payload(transmission_data); - *sample_final.user_header_mut() = header; - - sample_final.send() - .map_err(|e| UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to send: {e}")))?; - - Ok(()) - } -} - -#[async_trait] -impl UTransport for Iceoryx2Transport { - async fn send(&self, message: UMessage) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::Send { - message, - response: tx, - }; - - self.command_sender - .send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - rx.recv().map_err(|_| { - UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") - })? - } - - async fn register_listener( - &self, - source_filter: &UUri, - sink_filter: Option<&UUri>, - listener: Arc, - ) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::RegisterListener { - source_filter: source_filter.clone(), - sink_filter: sink_filter.cloned(), - response: tx, - }; - - self.command_sender - .send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - rx.recv().map_err(|_| { - UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") - })? - } - - async fn unregister_listener( - &self, - source_filter: &UUri, - sink_filter: Option<&UUri>, - listener: Arc, - ) -> Result<(), UStatus> { - let (tx, rx) = std::sync::mpsc::channel(); - - let command = TransportCommand::UnregisterListener { - source_filter: source_filter.clone(), - sink_filter: sink_filter.cloned(), - response: tx, - }; - - self.command_sender - .send(command) - .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; - - rx.recv().map_err(|_| { - UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") - })? - } -} - -fn test_uri(authority: &str, instance: u16, typ: u16, version: u8, resource: u16) -> UUri { - let entity_id = ((instance as u32) << 16) | (typ as u32); - UUri::try_from_parts(authority, entity_id, version, resource).unwrap() -} - -#[cfg(test)] -mod tests { - use super::*; - use up_rust::{UPayloadFormat, UStatus, UMessageBuilder}; - - use up_rust::UUID; - use std::convert::TryFrom; - - // fn dummy_uuid() -> up_rust::UUID { - // // let uuid = UUID::new(); - // let uuid = up_rust::UUID::new(); - // up_rust::UUID::try_from(uuid).expect("Valid UUID conversion") - // } - fn dummy_uuid() -> up_rust::UUID { - up_rust::UUID::build() - } - - // Helper function to create a test URI - fn test_uri(authority: &str, instance: u16, typ: u16, version: u8, resource: u16) -> UUri { - let entity_id = ((instance as u32) << 16) | (typ as u32); - UUri::try_from_parts(authority, entity_id, version, resource).unwrap() - } - - #[test] - fn test_publish_service_name() { - let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); - let message = UMessageBuilder::publish(source.clone()) - .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); - assert_eq!(name, "up/device1/10AB/0/3/80CD"); - } - - #[test] - fn test_notification_service_name() { - let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); - let sink = test_uri("device1", 0x0000, 0x30EF, 0x04, 0x0000); - let message = UMessageBuilder::notification(source.clone(), sink.clone()) - .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); - assert_eq!(name, "up/device1/10AB/0/3/80CD/device1/30EF/0/4/0"); - } - - #[test] - fn test_rpc_request_service_name() { - let sink = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); - let reply_to = test_uri("device1", 0x0000, 0x0001, 0x01, 0x0000); // Dummy reply URI - - let message = UMessageBuilder::request(sink.clone(), reply_to, 1000) - .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); - assert_eq!(name, "up/device1/CD/0/4/B"); - } - - - #[test] - fn test_rpc_response_service_name() { - let source = test_uri("device1", 0x0001, 0x0020, 0x01, 0x0000); - let sink = test_uri("device1", 0x0001, 0x00CD, 0x04, 0x1000); - let uuid = dummy_uuid(); - - let message = UMessageBuilder::response(source.clone(), uuid, sink.clone()) - .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); - - assert_eq!( - name, - "up/device1/CD/1/4/1000/device1/20/1/1/0" - ); - } - - - - #[test] - fn test_missing_uri_error() { - let message = UMessage::new(); // no source or sink - let result = Iceoryx2Transport::compute_service_name(&message); - - assert!(result.is_err()); - assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); - } -} +use async_trait::async_trait; +use iceoryx2::prelude::*; +use protobuf::MessageField; +use std::sync::Arc; +use up_rust::UAttributes; +use up_rust::{UCode, UListener, UMessage, UStatus, UTransport, UUri}; + +mod custom_header; +mod transmission_data; +pub use custom_header::CustomHeader; +pub use transmission_data::TransmissionData; + +use std::collections::HashMap; +use std::thread; + +enum TransportCommand { + Send { + message: UMessage, + response: std::sync::mpsc::Sender>, + }, + RegisterListener { + source_filter: UUri, + sink_filter: Option, + listener: Arc, + response: std::sync::mpsc::Sender>, + }, + UnregisterListener { + source_filter: UUri, + sink_filter: Option, + listener: Arc, + response: std::sync::mpsc::Sender>, + }, +} + +pub struct Iceoryx2Transport { + command_sender: std::sync::mpsc::Sender, +} + +impl Iceoryx2Transport { + pub fn new() -> Result { + let (tx, rx) = std::sync::mpsc::channel(); + + thread::spawn(move || { + Self::background_task(rx); + }); + + Ok(Self { command_sender: tx }) + } + + fn encode_uuri_segments(uuri: &UUri) -> Vec { + vec![ + uuri.authority_name.clone(), // e.g., "device1" + Self::encode_hex_no_leading_zeros(uuri.uentity_type_id() as u32), + Self::encode_hex_no_leading_zeros(uuri.uentity_instance_id() as u32), + Self::encode_hex_no_leading_zeros(uuri.uentity_major_version() as u32), + Self::encode_hex_no_leading_zeros(uuri.resource_id() as u32), + ] + } + + fn encode_hex_no_leading_zeros(value: u32) -> String { + format!("{:X}", value) + } + + // returns a correct iceoryx2 service name based on the UMessage type + // and its source/sink URIs. + fn compute_service_name(message: &UMessage) -> Result { + let join_segments = |segments: Vec| segments.join("/"); + + if message.is_publish() { + let source = message.source().ok_or_else(|| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI") + })?; + let segments = Self::encode_uuri_segments(source); + Ok(format!("up/{}", join_segments(segments))) + } else if message.is_request() { + let sink = message.sink().ok_or_else(|| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI") + })?; + let segments = Self::encode_uuri_segments(sink); + Ok(format!("up/{}", join_segments(segments))) + } else if message.is_response() || message.is_notification() { + let source = message.source().ok_or_else(|| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing source URI") + })?; + let sink = message.sink().ok_or_else(|| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Missing sink URI") + })?; + + let source_segments = Self::encode_uuri_segments(source); + let sink_segments = Self::encode_uuri_segments(sink); + Ok(format!( + "up/{}/{}", + join_segments(source_segments), + join_segments(sink_segments) + )) + } else { + Err(UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + "Unsupported UMessageType", + )) + } + } + + fn compute_listener_service_name( + source_filter: &UUri, + sink_filter: Option<&UUri>, + ) -> Result { + let join_segments = |segments: Vec| segments.join("/"); + + match sink_filter { + None => { + // Publish subscription. + let segments = Self::encode_uuri_segments(source_filter); + Ok(format!("up/{}", join_segments(segments))) + } + Some(sink) => { + let is_wildcard_entity = source_filter.uentity_type_id() == 0xFFFF + && source_filter.uentity_instance_id() == 0xFFFF; + let is_wildcard_version = source_filter.uentity_major_version() == 0xFF; + let is_wildcard_resource = source_filter.resource_id() == 0xFFFF; + + if is_wildcard_entity && is_wildcard_version && is_wildcard_resource { + // Request subscription. + let segments = Self::encode_uuri_segments(sink); + Ok(format!("up/{}", join_segments(segments))) + } else { + // Notification or Response subscription. + let source_segments = Self::encode_uuri_segments(source_filter); + let sink_segments = Self::encode_uuri_segments(sink); + Ok(format!( + "up/{}/{}", + join_segments(source_segments), + join_segments(sink_segments) + )) + } + } + } + } + + fn background_task(rx: std::sync::mpsc::Receiver) { + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Failed to create Tokio runtime"); + + rt.block_on(async { + let node = match NodeBuilder::new().create::() { + Ok(node) => node, + Err(e) => { + eprintln!("Failed to create iceoryx2 node: {}", e); + return; + } + }; + + let mut publishers: HashMap< + String, + iceoryx2::port::publisher::Publisher, + > = HashMap::new(); + let mut subscribers: HashMap< + String, + iceoryx2::port::subscriber::Subscriber< + ipc::Service, + TransmissionData, + CustomHeader, + >, + > = HashMap::new(); + let mut listeners: HashMap>> = HashMap::new(); + + loop { + // 1. Process all pending commands + while let Ok(command) = rx.try_recv() { + match command { + TransportCommand::Send { message, response } => { + let service_name = match Self::compute_service_name(&message) { + Ok(name) => name, + Err(e) => { + let _ = response.send(Err(e)); + continue; + } + }; + + let publisher = + publishers.entry(service_name.clone()).or_insert_with(|| { + let service_name_res: Result = + service_name.as_str().try_into(); + let service = node + .service_builder(&service_name_res.unwrap()) + .publish_subscribe::() + .user_header::() + .open_or_create() + .expect("Failed to create service"); + + service + .publisher_builder() + .create() + .expect("Failed to create publisher") + }); + + let result = Self::handle_send(publisher, message); + let _ = response.send(result); + } + TransportCommand::RegisterListener { + source_filter, + sink_filter, + listener, + response, + } => { + let res = Self::handle_register_listener( + &node, + &mut subscribers, + &mut listeners, + source_filter, + sink_filter.as_ref(), + listener, + ); + let _ = response.send(res); + } + TransportCommand::UnregisterListener { + source_filter, + sink_filter, + listener, + response, + } => { + let res = Self::handle_unregister_listener( + &mut subscribers, + &mut listeners, + source_filter, + sink_filter.as_ref(), + &listener, + ); + let _ = response.send(res); + } + } + } + + // 2. Poll all subscribers for new messages + for (service_name, subscriber) in subscribers.iter() { + while let Some(sample) = subscriber.receive().ok().flatten() { + if let Some(listeners) = listeners.get(service_name) { + for listener in listeners { + let mut new_umessage = UMessage::new(); + new_umessage.attributes = + MessageField::some(UAttributes::from(sample.user_header())); + new_umessage.payload = Some(sample.payload().to_bytes().into()); + let listener_clone = listener.clone(); + tokio::spawn(async move { + listener_clone.on_receive(new_umessage).await; + }); + } + } + } + } + + // Avoid busy-waiting + tokio::time::sleep(std::time::Duration::from_millis(10)).await; + } + }); + } + + fn handle_unregister_listener( + subscribers: &mut HashMap< + String, + iceoryx2::port::subscriber::Subscriber, + >, + listeners: &mut HashMap>>, + source_filter: UUri, + sink_filter: Option<&UUri>, + listener: &Arc, + ) -> Result<(), UStatus> { + let service_name = match Self::compute_listener_service_name(&source_filter, sink_filter) { + Ok(name) => name, + Err(e) => { + return Err(e); + } + }; + + if let Some(listener_vec) = listeners.get_mut(&service_name) { + // Remove the listener by comparing memory addresses. + listener_vec.retain(|l| !Arc::ptr_eq(l, listener)); + + // If no listeners are left for this service, remove the subscriber. + if listener_vec.is_empty() { + listeners.remove(&service_name); + subscribers.remove(&service_name); + } + } + + Ok(()) + } + + fn handle_register_listener( + node: &Node, + subscribers: &mut HashMap< + String, + iceoryx2::port::subscriber::Subscriber, + >, + listeners: &mut HashMap>>, + source_filter: UUri, + sink_filter: Option<&UUri>, + listener: Arc, + ) -> Result<(), UStatus> { + let service_name = match Self::compute_listener_service_name(&source_filter, sink_filter) { + Ok(name) => name, + Err(e) => { + return Err(e); + } + }; + + if !subscribers.contains_key(&service_name) { + let service_name_res: Result = service_name.as_str().try_into(); + let service = node + .service_builder(&service_name_res.unwrap()) + .publish_subscribe::() + .user_header::() + .open_or_create() + .expect("Failed to create service"); + + let subscriber = service + .subscriber_builder() + .create() + .expect("Failed to create subscriber"); + subscribers.insert(service_name.clone(), subscriber); + } + + listeners.entry(service_name).or_default().push(listener); + Ok(()) + } + + fn handle_send( + publisher: &iceoryx2::port::publisher::Publisher< + ipc::Service, + TransmissionData, + CustomHeader, + >, + message: UMessage, + ) -> Result<(), UStatus> { + let transmission_data = TransmissionData::from_message(&message)?; + let header = CustomHeader::from_message(&message)?; + + let sample = publisher.loan_uninit().map_err(|e| { + UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")) + })?; + + let mut sample_final = sample.write_payload(transmission_data); + *sample_final.user_header_mut() = header; + + sample_final.send().map_err(|e| { + UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to send: {e}")) + })?; + + Ok(()) + } +} + +#[async_trait] +impl UTransport for Iceoryx2Transport { + async fn send(&self, message: UMessage) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::Send { + message, + response: tx, + }; + + self.command_sender + .send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv().map_err(|_| { + UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") + })? + } + + async fn register_listener( + &self, + source_filter: &UUri, + sink_filter: Option<&UUri>, + listener: Arc, + ) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::RegisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + listener, + response: tx, + }; + + self.command_sender + .send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv().map_err(|_| { + UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") + })? + } + + async fn unregister_listener( + &self, + source_filter: &UUri, + sink_filter: Option<&UUri>, + listener: Arc, + ) -> Result<(), UStatus> { + let (tx, rx) = std::sync::mpsc::channel(); + + let command = TransportCommand::UnregisterListener { + source_filter: source_filter.clone(), + sink_filter: sink_filter.cloned(), + listener, + response: tx, + }; + + self.command_sender + .send(command) + .map_err(|_| UStatus::fail_with_code(UCode::INTERNAL, "Background task has died"))?; + + rx.recv().map_err(|_| { + UStatus::fail_with_code(UCode::INTERNAL, "Background task response failed") + })? + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::atomic::{AtomicBool, Ordering}; + use std::time::Duration; + use up_rust::{UMessageBuilder, UPayloadFormat}; + + // fn dummy_uuid() -> up_rust::UUID { + // // let uuid = UUID::new(); + // let uuid = up_rust::UUID::new(); + // up_rust::UUID::try_from(uuid).expect("Valid UUID conversion") + // } + fn dummy_uuid() -> up_rust::UUID { + up_rust::UUID::build() + } + + // Helper function to create a test URI + fn test_uri(authority: &str, instance: u16, typ: u16, version: u8, resource: u16) -> UUri { + let entity_id = ((instance as u32) << 16) | (typ as u32); + UUri::try_from_parts(authority, entity_id, version, resource).unwrap() + } + + #[test] + fn test_publish_service_name() { + let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); + let message = UMessageBuilder::publish(source.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/10AB/0/3/80CD"); + } + + #[test] + fn test_notification_service_name() { + let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); + let sink = test_uri("device1", 0x0000, 0x30EF, 0x04, 0x0000); + let message = UMessageBuilder::notification(source.clone(), sink.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/10AB/0/3/80CD/device1/30EF/0/4/0"); + } + + #[test] + fn test_rpc_request_service_name() { + let sink = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); + let reply_to = test_uri("device1", 0x0000, 0x0001, 0x01, 0x0000); // Dummy reply URI + + let message = UMessageBuilder::request(sink.clone(), reply_to, 1000) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/CD/0/4/B"); + } + + #[test] + fn test_rpc_response_service_name() { + let source = test_uri("device1", 0x0001, 0x0020, 0x01, 0x0000); + let sink = test_uri("device1", 0x0001, 0x00CD, 0x04, 0x1000); + let uuid = dummy_uuid(); + + let message = UMessageBuilder::response(source.clone(), uuid, sink.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + + assert_eq!(name, "up/device1/CD/1/4/1000/device1/20/1/1/0"); + } + + #[test] + fn test_missing_uri_error() { + let message = UMessage::new(); // no source or sink + let result = Iceoryx2Transport::compute_service_name(&message); + + assert!(result.is_err()); + assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); + } + + #[tokio::test] + async fn test_register_listener_and_receive() { + struct TestListener { + received: Arc, + } + + #[async_trait::async_trait] + impl UListener for TestListener { + async fn on_receive(&self, _message: UMessage) { + println!("TestListener received a message!"); + self.received.store(true, Ordering::SeqCst); + } + } + + let transport = Iceoryx2Transport::new().unwrap(); + let source_uri = test_uri("test_authority", 0, 1, 1, 0x8001); + + let received = Arc::new(AtomicBool::new(false)); + let listener = Arc::new(TestListener { + received: received.clone(), + }); + + transport + .register_listener(&source_uri, None, listener) + .await + .unwrap(); + + // Give a moment for registration to complete + tokio::time::sleep(Duration::from_millis(100)).await; + + let data = TransmissionData { + x: 1, + y: 2, + funky: 3.14, + }; + let payload_bytes = data.to_bytes(); + + let msg = UMessageBuilder::publish(source_uri) + .build_with_payload(payload_bytes, UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + transport.send(msg).await.unwrap(); + + // Give a moment for the message to be received + tokio::time::sleep(Duration::from_millis(200)).await; + + assert!(received.load(Ordering::SeqCst)); + } + + #[tokio::test] + async fn test_unregister_listener() { + struct TestListener { + received: Arc, + } + + #[async_trait::async_trait] + impl UListener for TestListener { + async fn on_receive(&self, _message: UMessage) { + self.received.store(true, Ordering::SeqCst); + } + } + + let transport = Iceoryx2Transport::new().unwrap(); + let source_uri = test_uri("test_authority", 0, 1, 1, 0x8002); + + let received = Arc::new(AtomicBool::new(false)); + let listener = Arc::new(TestListener { + received: received.clone(), + }); + + transport + .register_listener(&source_uri, None, listener.clone()) + .await + .unwrap(); + transport + .unregister_listener(&source_uri, None, listener) + .await + .unwrap(); + + // Give a moment for unregistration to complete + tokio::time::sleep(Duration::from_millis(100)).await; + + let data = TransmissionData { + x: 1, + y: 2, + funky: 3.14, + }; + let payload_bytes = data.to_bytes(); + + let msg = UMessageBuilder::publish(source_uri) + .build_with_payload(payload_bytes, UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + transport.send(msg).await.unwrap(); + + // Give a moment for the message to be (or not be) received + tokio::time::sleep(Duration::from_millis(200)).await; + + assert!(!received.load(Ordering::SeqCst)); + + // Give a moment for the service to be deallocated + tokio::time::sleep(Duration::from_millis(100)).await; + } +} diff --git a/src/receiver.rs b/src/receiver.rs index dff7f56..721740e 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -23,24 +23,22 @@ impl Receiver{ } #[async_trait] -impl UListener for Receiver{ - async fn on_receive(&self,message:UMessage)->UStatus{ - if let Some(payload)=message.payload(){ - println!("Receieved Message ID: {}", message.id()); +impl UListener for Receiver { + async fn on_receive(&self, message: UMessage) { + if message.payload().is_some() { + println!("Received Message ID: {}", message.id()); } - - UStatus::Ok } } -#[tokio::test] -async fn test_receiver(){ - let receiver= Receiver::new(); - let transport = Iceoryx2Transport::new().unwrap(); - source_URI= UUri - sink_filter= - transport.register_listener(receiver).await.unwrap(); - -} - - +// #[tokio::test] +// async fn test_receiver() { +// let receiver = Receiver::new(); +// let transport = Iceoryx2Transport::new().unwrap(); +// let source_uri = UUri::default(); +// let sink_filter = None; +// transport +// .register_listener(&source_uri, sink_filter, Arc::new(receiver)) +// .await +// .unwrap(); +// } diff --git a/src/test.rs b/src/test.rs deleted file mode 100644 index 365464f..0000000 --- a/src/test.rs +++ /dev/null @@ -1,189 +0,0 @@ -use super::*; -use bytes::Bytes; -use std::sync::Arc; -use up_rust::{UMessageBuilder, UPayloadFormat, UUri}; - -use protobuf::MessageField; // if you use this in tests - -// Example synchronous test (no async needed) -works -#[test] -fn test_custom_header_from_user_header() { - let header = CustomHeader { version: 2, timestamp: 1000 }; - let new_header = CustomHeader::from_user_header(&header).unwrap(); - assert_eq!(new_header.version, 2); - assert_eq!(new_header.timestamp, 1000); -} - -// Async test requires Tokio runtime - work -#[tokio::test] -async fn test_transport_creation() { - let transport = Iceoryx2Transport::new(); - assert!(transport.is_ok()); -} - -//checks that umessage is correctly parsed into transmission data - works -#[test] -fn test_transmission_data_from_message() { - let data = TransmissionData { - x: 42, - y: -7, - funky: 3.14, - }; - - let bytes = data.to_bytes(); - let mut msg = UMessage::new(); - msg.payload = Some(Bytes::from(bytes)); - - let result = TransmissionData::from_message(&msg); - assert!(result.is_ok()); - let decoded = result.unwrap(); - assert_eq!(decoded.x, 42); - assert_eq!(decoded.y, -7); - assert!((decoded.funky - 3.14).abs() < 1e-6); -} - -//checks that custom header w missing fields works fine - works -#[test] -fn test_custom_header_missing_fields() { - let msg = UMessage::new(); // No attributes set - let result = CustomHeader::from_message(&msg); - assert!(result.is_ok()); // Still shouldn't panic -} - -//checks multiple messages which are sent in sequence - works -#[tokio::test] -async fn test_multiple_sends() { - let transport = Iceoryx2Transport::new().unwrap(); - - for i in 0..5 { - //creating valid transmission data instance - let data = TransmissionData { - x: i, - y: i * 10, - funky: i as f64 + 0.5, - }; - - // convert to bytes - let bytes = data.to_bytes(); - - // wrap in umessage and send - let authority = format!("sensor{}", i); - let uri = UUri::try_from_parts(&authority, 0xA100, 0x01, 0x8001) - .unwrap_or_else(|e| panic!("Failed to construct URI for '{}': {:?}", authority, e)); - - - let msg = UMessageBuilder::publish(uri) - .build_with_payload(data.to_bytes(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let result = transport.send(msg).await; - - if let Err(e) = &result { - } - - assert!(result.is_ok()); - } -} - -//sending an empty payload - works -#[tokio::test] -async fn test_send_empty_payload() { - let transport = Iceoryx2Transport::new().unwrap(); - - let message = UMessage { - payload: Some(Bytes::from(vec![])), // empty payload - ..Default::default() - }; - - let result = transport.send(message).await; - - // It might be valid or invalid depending on implementation - assert!(result.is_ok() || result.is_err()); -} - -//sending without a payload - works -#[tokio::test] -async fn test_send_no_payload() { - let transport = Iceoryx2Transport::new().unwrap(); - - let message = UMessage::default(); // no payload at all - - let result = transport.send(message).await; - - assert!(result.is_err(), "Expected error when sending without payload"); -} - -//sending a max_sized payload - works -#[tokio::test] -async fn test_send_large_payload() { - let transport = Iceoryx2Transport::new().unwrap(); - - let max_size_payload = vec![0xAB; 1024 * 1024]; // 1MB - let message = UMessage { - payload: Some(Bytes::from(max_size_payload)), - ..Default::default() - }; - - let result = transport.send(message).await; - - assert!(result.is_ok() || result.is_err()); // depends on your transport's buffer limit -} - -//sending multiple concurrent messages - works -#[tokio::test] -async fn test_concurrent_sends() { - let transport = Iceoryx2Transport::new().unwrap(); - let transport = Arc::new(transport); - - let mut handles = vec![]; - - for i in 0..10 { - let transport_clone = Arc::clone(&transport); - handles.push(tokio::spawn(async move { - let data = TransmissionData { - x: i, - y: i * 2, - funky: i as f64 * 1.1, - }; - - let authority = format!("vehicle{}", i); - let uri = UUri::try_from_parts(&authority, 0xA100, 0x01, 0x8001) - .unwrap_or_else(|e| panic!("Failed to construct URI for '{}': {:?}", authority, e)); - - - let msg = UMessageBuilder::publish(uri) - .build_with_payload(data.to_bytes(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - transport_clone.send(msg).await - })); - } - - for handle in handles { - let result = handle.await.unwrap(); - assert!(result.is_ok()); - } -} - - - -#[tokio::test] // works -async fn test_send_message() { - if let Ok(transport) = Iceoryx2Transport::new() { - let uprotocol_header = CustomHeader { - version: 1, - timestamp: 123456789, - }; - - let message = UMessage { - attributes: MessageField::some(UAttributes::from(&uprotocol_header)), - payload: Some(vec![1, 2, 3, 4].into()), - ..Default::default() - }; - - let result = transport.send(message).await; - - // It might fail if no background service is running, so accept Ok or Err. - assert!(result.is_ok() || result.is_err()); - } -} \ No newline at end of file diff --git a/src/transmission_data.rs b/src/transmission_data.rs index cf82a8f..76488ba 100644 --- a/src/transmission_data.rs +++ b/src/transmission_data.rs @@ -1,62 +1,60 @@ -// Copyright (c) 2023 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache Software License 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license -// which is available at https://opensource.org/licenses/MIT. -// -// SPDX-License-Identifier: Apache-2.0 OR MIT - -use iceoryx2::prelude::*; -use up_rust::{UMessage, UStatus, UCode}; -use bytes::Bytes; - -#[derive(Debug, Clone, Copy, ZeroCopySend, Default)] -// optional type name; if not set, `core::any::type_name::()` is used -#[type_name("TransmissionData")] -#[repr(C)] -pub struct TransmissionData { - pub x: i32, - pub y: i32, - pub funky: f64, -} - -impl TransmissionData { - pub fn from_bytes(bytes: Vec) -> Result { - if bytes.len() != std::mem::size_of::() { - return Err(UStatus::fail_with_code( - UCode::INVALID_ARGUMENT, - "Invalid byte length for TransmissionData", - )); - } - - let mut data = Self { - x: 0, - y: 0, - funky: 0.0, - }; - let ptr = &mut data as *mut Self as *mut u8; - unsafe { - std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, bytes.len()); - } - Ok(data) - } - - - pub fn to_bytes(&self) -> Vec { - let mut bytes = vec![0u8; std::mem::size_of::()]; - let ptr = self as *const Self as *const u8; - unsafe { - std::ptr::copy_nonoverlapping(ptr, bytes.as_mut_ptr(), bytes.len()); - } - bytes - } - - pub fn from_message(message: &UMessage) -> Result { - let payload = message.payload.clone().unwrap_or_default(); - Self::from_bytes(payload.to_vec()) - } -} \ No newline at end of file +// Copyright (c) 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use iceoryx2::prelude::*; +use up_rust::{UCode, UMessage, UStatus}; + +#[derive(Debug, Clone, Copy, ZeroCopySend, Default)] +// optional type name; if not set, `core::any::type_name::()` is used +#[type_name("TransmissionData")] +#[repr(C)] +pub struct TransmissionData { + pub x: i32, + pub y: i32, + pub funky: f64, +} + +impl TransmissionData { + pub fn from_bytes(bytes: Vec) -> Result { + if bytes.len() != std::mem::size_of::() { + return Err(UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + "Invalid byte length for TransmissionData", + )); + } + + let mut data = Self { + x: 0, + y: 0, + funky: 0.0, + }; + let ptr = &mut data as *mut Self as *mut u8; + unsafe { + std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, bytes.len()); + } + Ok(data) + } + + pub fn to_bytes(&self) -> Vec { + let mut bytes = vec![0u8; std::mem::size_of::()]; + let ptr = self as *const Self as *const u8; + unsafe { + std::ptr::copy_nonoverlapping(ptr, bytes.as_mut_ptr(), bytes.len()); + } + bytes + } + + pub fn from_message(message: &UMessage) -> Result { + let payload = message.payload.clone().unwrap_or_default(); + Self::from_bytes(payload.to_vec()) + } +} From 33f3303648fbd7f086a1ae39cb516f395b768181 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 3 Jul 2025 20:05:44 -0500 Subject: [PATCH 20/42] mostly fixing the failing tests, only one test the wildcard is failing- will fix this but i want the functional code to be commited so in case i can go back to it --- Cargo.lock | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 ++ src/receiver.rs | 15 ++++++-- 3 files changed, 108 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bba27da..3f04b40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,6 +143,12 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + [[package]] name = "byteorder" version = "1.5.0" @@ -578,6 +584,16 @@ dependencies = [ "syn", ] +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -1063,6 +1079,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + [[package]] name = "scopeguard" version = "1.2.0" @@ -1360,10 +1382,12 @@ dependencies = [ "env_logger", "iceoryx2", "log", + "once_cell", "protobuf", "test-case", "tokio", "up-rust", + "uuid", ] [[package]] @@ -1382,6 +1406,17 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +dependencies = [ + "getrandom 0.3.3", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "uuid-simd" version = "0.8.0" @@ -1413,6 +1448,64 @@ dependencies = [ "wit-bindgen-rt", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + [[package]] name = "which" version = "4.4.2" diff --git a/Cargo.toml b/Cargo.toml index 4e0dc9a..db4c260 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,9 @@ tokio = { version = "1", features = ["full"] } test-case = "3" log = "0.4.27" env_logger = "0.11.8" +once_cell = "1.18.0" +uuid = { version = "1", features = ["v4"] } + [dev-dependencies] up-rust = { version = "0.5.0", features = ["test-util"] } diff --git a/src/receiver.rs b/src/receiver.rs index 7e8911d..ec1cf8a 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -17,6 +17,8 @@ use env_logger; use std::sync::Once; + + static INIT_LOGGER: Once = Once::new(); fn init_logger() { @@ -46,7 +48,11 @@ impl UListener for Receiver{ async fn on_receive(&self,message:UMessage)->(){ if let Some(payload)=&message.payload{ println!("Receieved Message ID: {:#?}", message.id()); - assert_eq!(self.expected, message); + if let (Some(expected_payload), Some(actual_payload)) = (&self.expected.payload, &message.payload) { + assert_eq!(expected_payload, actual_payload); + } else { + panic!("Missing payloads in either expected or actual message"); + } self.notify.notify_one(); } } @@ -97,12 +103,15 @@ async fn test_publish_gets_to_listener( source_filter_uri: &str, ) -> Result<(), Box> { let topic = UUri::from_str(topic_uri)?; - let source_filter = UUri::from_str(source_filter_uri)?; + let source_filter = topic.clone(); + let data = TransmissionData { x: 1, y: 2, funky: 3.14 }; + let payload = data.to_bytes(); + let umessage = UMessageBuilder::publish(topic.clone()) .with_priority(up_rust::UPriority::UPRIORITY_CS5) .with_traceparent("traceparent") .with_ttl(ttl) - .build_with_payload(MESSAGE_DATA, UPayloadFormat::UPAYLOAD_FORMAT_TEXT)?; + .build_with_payload(payload, UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; register_listener_and_send(authority, umessage, &source_filter, None).await } From 8b8b170a8761687cfce827b74ddc24719dcf2862 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 3 Jul 2025 20:51:57 -0500 Subject: [PATCH 21/42] creating it so that it sends and recives on seperate terminals --- Cargo.toml | 1 + src/bin/listener.rs | 57 +++++++++++++++++++++++++++++++++++++++ src/bin/sender.rs | 66 ++++++++++++++++++++++----------------------- 3 files changed, 90 insertions(+), 34 deletions(-) create mode 100644 src/bin/listener.rs diff --git a/Cargo.toml b/Cargo.toml index db4c260..6f6c533 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,3 +19,4 @@ uuid = { version = "1", features = ["v4"] } [dev-dependencies] up-rust = { version = "0.5.0", features = ["test-util"] } + diff --git a/src/bin/listener.rs b/src/bin/listener.rs new file mode 100644 index 0000000..0ab87c1 --- /dev/null +++ b/src/bin/listener.rs @@ -0,0 +1,57 @@ +use std::sync::Arc; +use tokio::sync::Notify; +use async_trait::async_trait; +use up_rust::{UListener, UMessage, UUri}; +use env_logger; +use std::sync::Once; +use std::str::FromStr; +use up_rust::UTransport; +use up_transport_iceoryx2_rust::{Iceoryx2Transport, TransmissionData}; + +static INIT_LOGGER: Once = Once::new(); + +fn init_logger() { + INIT_LOGGER.call_once(|| { + env_logger::init(); + }); +} + +pub struct Receiver { + notify: Arc, +} + +#[async_trait] +impl UListener for Receiver { + async fn on_receive(&self, message: UMessage) { + // Optional: deserialize payload to TransmissionData + if let Some(payload) = &message.payload { + match TransmissionData::from_bytes(payload.to_vec()) { + Ok(data) => println!("Received data: {:?}", data), + Err(_) => println!("Received message but failed to decode payload."), + } + } else { + println!("Received message with no payload."); + } + self.notify.notify_one(); + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + init_logger(); + + let notify = Arc::new(Notify::new()); + let receiver = Arc::new(Receiver { notify: notify.clone() }); + + let topic = UUri::from_str("//vehicle_shared/10A10B/1/CA5D")?; + let transport = Iceoryx2Transport::new().unwrap(); + + transport.register_listener(&topic, None, receiver).await?; + + println!("Listener started, waiting for messages..."); + + loop { + notify.notified().await; + println!("Message received."); + } +} diff --git a/src/bin/sender.rs b/src/bin/sender.rs index b984807..21ac61b 100644 --- a/src/bin/sender.rs +++ b/src/bin/sender.rs @@ -1,39 +1,37 @@ +use up_rust::{UMessageBuilder, UPayloadFormat, UUri}; +use env_logger; +use std::sync::Once; +use std::str::FromStr; use up_transport_iceoryx2_rust::{Iceoryx2Transport, TransmissionData}; -use up_rust::{UTransport, UMessageBuilder, UPayloadFormat, UUri}; +use up_rust::UTransport; + + +static INIT_LOGGER: Once = Once::new(); + +fn init_logger() { + INIT_LOGGER.call_once(|| { + env_logger::init(); + }); +} #[tokio::main] -async fn main() { - println!("Starting sender application..."); - - let transport = match Iceoryx2Transport::new() { - Ok(t) => t, - Err(e) => { - eprintln!("Failed to create transport: {:?}", e); - return; - } - }; - - // Define a topic URI to publish to - let source_uri = UUri::try_from_parts("vehicle", 0x1000, 1, 0x8001).unwrap(); - - // Create a sample payload - let data = TransmissionData { - x: 123, - y: 456, - funky: 9.87, - }; - let payload_bytes = data.to_bytes(); - - // Build the UMessage - let msg = UMessageBuilder::publish(source_uri.clone()) - .build_with_payload(payload_bytes, UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .expect("Failed to build message"); - - println!("Sending message to URI: {}", source_uri); - - // Send the message - match transport.send(msg).await { - Ok(_) => println!("Message sent successfully!"), - Err(e) => eprintln!("Failed to send message: {:?}", e), +async fn main() -> Result<(), Box> { + init_logger(); + + let topic = UUri::from_str("//vehicle_shared/10A10B/1/CA5D")?; + let transport = Iceoryx2Transport::new().unwrap(); + + loop { + let data = TransmissionData { x: 1, y: 2, funky: 3.14 }; + let payload = data.to_bytes(); + + let umessage = UMessageBuilder::publish(topic.clone()) + .build_with_payload(payload, UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; + + transport.send(umessage).await?; + + println!("Message sent."); + + tokio::time::sleep(std::time::Duration::from_secs(1)).await; } } From 418af5bc026fcc117a31defcccdc23e4b7b862d4 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Tue, 8 Jul 2025 12:56:46 -0500 Subject: [PATCH 22/42] made the transmission data completely genetic --- src/bin/listener.rs | 11 +-- src/bin/sender.rs | 9 ++- src/lib.rs | 150 ++++++++++++++++++++++++++------------- src/raw_bytes.rs | 24 +++++++ src/receiver.rs | 33 +++------ src/transmission_data.rs | 4 ++ 6 files changed, 146 insertions(+), 85 deletions(-) create mode 100644 src/raw_bytes.rs diff --git a/src/bin/listener.rs b/src/bin/listener.rs index 0ab87c1..b4cefdd 100644 --- a/src/bin/listener.rs +++ b/src/bin/listener.rs @@ -1,12 +1,11 @@ use std::sync::Arc; use tokio::sync::Notify; use async_trait::async_trait; -use up_rust::{UListener, UMessage, UUri}; +use up_rust::{UListener, UMessage, UUri, UTransport}; use env_logger; use std::sync::Once; use std::str::FromStr; -use up_rust::UTransport; -use up_transport_iceoryx2_rust::{Iceoryx2Transport, TransmissionData}; +use up_transport_iceoryx2_rust::Iceoryx2Transport; static INIT_LOGGER: Once = Once::new(); @@ -23,12 +22,8 @@ pub struct Receiver { #[async_trait] impl UListener for Receiver { async fn on_receive(&self, message: UMessage) { - // Optional: deserialize payload to TransmissionData if let Some(payload) = &message.payload { - match TransmissionData::from_bytes(payload.to_vec()) { - Ok(data) => println!("Received data: {:?}", data), - Err(_) => println!("Received message but failed to decode payload."), - } + println!("Received payload bytes: {:?}", payload); } else { println!("Received message with no payload."); } diff --git a/src/bin/sender.rs b/src/bin/sender.rs index 21ac61b..08a4a99 100644 --- a/src/bin/sender.rs +++ b/src/bin/sender.rs @@ -1,10 +1,9 @@ -use up_rust::{UMessageBuilder, UPayloadFormat, UUri}; use env_logger; use std::sync::Once; use std::str::FromStr; -use up_transport_iceoryx2_rust::{Iceoryx2Transport, TransmissionData}; -use up_rust::UTransport; +use up_rust::{UMessageBuilder, UPayloadFormat, UUri, UTransport}; +use up_transport_iceoryx2_rust::Iceoryx2Transport; static INIT_LOGGER: Once = Once::new(); @@ -22,8 +21,8 @@ async fn main() -> Result<(), Box> { let transport = Iceoryx2Transport::new().unwrap(); loop { - let data = TransmissionData { x: 1, y: 2, funky: 3.14 }; - let payload = data.to_bytes(); + // byte array payload + let payload: Vec = vec![1, 2, 3, 4, 5, 6]; let umessage = UMessageBuilder::publish(topic.clone()) .build_with_payload(payload, UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; diff --git a/src/lib.rs b/src/lib.rs index 8a48ba5..b4d8e0c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,13 +2,13 @@ use async_trait::async_trait; use iceoryx2::prelude::*; use protobuf::MessageField; use std::sync::Arc; -use up_rust::UAttributes; -use up_rust::{UCode, UListener, UMessage, UStatus, UTransport, UUri}; +use up_rust::{UAttributes, UCode, UListener, UMessage, UStatus, UTransport, UUri}; mod custom_header; -mod transmission_data; pub use custom_header::CustomHeader; -pub use transmission_data::TransmissionData; + +mod raw_bytes; +use raw_bytes::RawBytes; use std::collections::HashMap; use std::thread; @@ -49,7 +49,7 @@ impl Iceoryx2Transport { fn encode_uuri_segments(uuri: &UUri) -> Vec { vec![ - uuri.authority_name.clone(), // e.g., "device1" + uuri.authority_name.clone(), Self::encode_hex_no_leading_zeros(uuri.uentity_type_id() as u32), Self::encode_hex_no_leading_zeros(uuri.uentity_instance_id() as u32), Self::encode_hex_no_leading_zeros(uuri.uentity_major_version() as u32), @@ -61,8 +61,6 @@ impl Iceoryx2Transport { format!("{:X}", value) } - // returns a correct iceoryx2 service name based on the UMessage type - // and its source/sink URIs. fn compute_service_name(message: &UMessage) -> Result { let join_segments = |segments: Vec| segments.join("/"); @@ -109,7 +107,6 @@ impl Iceoryx2Transport { match sink_filter { None => { - // Publish subscription. let segments = Self::encode_uuri_segments(source_filter); Ok(format!("up/{}", join_segments(segments))) } @@ -120,11 +117,9 @@ impl Iceoryx2Transport { let is_wildcard_resource = source_filter.resource_id() == 0xFFFF; if is_wildcard_entity && is_wildcard_version && is_wildcard_resource { - // Request subscription. let segments = Self::encode_uuri_segments(sink); Ok(format!("up/{}", join_segments(segments))) } else { - // Notification or Response subscription. let source_segments = Self::encode_uuri_segments(source_filter); let sink_segments = Self::encode_uuri_segments(sink); Ok(format!( @@ -154,20 +149,17 @@ impl Iceoryx2Transport { let mut publishers: HashMap< String, - iceoryx2::port::publisher::Publisher, + iceoryx2::port::publisher::Publisher, > = HashMap::new(); + let mut subscribers: HashMap< String, - iceoryx2::port::subscriber::Subscriber< - ipc::Service, - TransmissionData, - CustomHeader, - >, + iceoryx2::port::subscriber::Subscriber, > = HashMap::new(); + let mut listeners: HashMap>> = HashMap::new(); loop { - // 1. Process all pending commands while let Ok(command) = rx.try_recv() { match command { TransportCommand::Send { message, response } => { @@ -185,7 +177,7 @@ impl Iceoryx2Transport { service_name.as_str().try_into(); let service = node .service_builder(&service_name_res.unwrap()) - .publish_subscribe::() + .publish_subscribe::() .user_header::() .open_or_create() .expect("Failed to create service"); @@ -233,7 +225,6 @@ impl Iceoryx2Transport { } } - // 2. Poll all subscribers for new messages for (service_name, subscriber) in subscribers.iter() { while let Some(sample) = subscriber.receive().ok().flatten() { if let Some(listeners) = listeners.get(service_name) { @@ -251,7 +242,6 @@ impl Iceoryx2Transport { } } - // Avoid busy-waiting tokio::time::sleep(std::time::Duration::from_millis(10)).await; } }); @@ -260,7 +250,7 @@ impl Iceoryx2Transport { fn handle_unregister_listener( subscribers: &mut HashMap< String, - iceoryx2::port::subscriber::Subscriber, + iceoryx2::port::subscriber::Subscriber, >, listeners: &mut HashMap>>, source_filter: UUri, @@ -275,10 +265,7 @@ impl Iceoryx2Transport { }; if let Some(listener_vec) = listeners.get_mut(&service_name) { - // Remove the listener by comparing memory addresses. listener_vec.retain(|l| !Arc::ptr_eq(l, listener)); - - // If no listeners are left for this service, remove the subscriber. if listener_vec.is_empty() { listeners.remove(&service_name); subscribers.remove(&service_name); @@ -292,7 +279,7 @@ impl Iceoryx2Transport { node: &Node, subscribers: &mut HashMap< String, - iceoryx2::port::subscriber::Subscriber, + iceoryx2::port::subscriber::Subscriber, >, listeners: &mut HashMap>>, source_filter: UUri, @@ -310,7 +297,7 @@ impl Iceoryx2Transport { let service_name_res: Result = service_name.as_str().try_into(); let service = node .service_builder(&service_name_res.unwrap()) - .publish_subscribe::() + .publish_subscribe::() .user_header::() .open_or_create() .expect("Failed to create service"); @@ -329,19 +316,20 @@ impl Iceoryx2Transport { fn handle_send( publisher: &iceoryx2::port::publisher::Publisher< ipc::Service, - TransmissionData, + RawBytes, CustomHeader, >, message: UMessage, ) -> Result<(), UStatus> { - let transmission_data = TransmissionData::from_message(&message)?; + let payload_bytes = message.payload.clone().unwrap_or_default().to_vec(); + let raw_payload = RawBytes::from_bytes(payload_bytes); let header = CustomHeader::from_message(&message)?; let sample = publisher.loan_uninit().map_err(|e| { UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")) })?; - let mut sample_final = sample.write_payload(transmission_data); + let mut sample_final = sample.write_payload(raw_payload); *sample_final.user_header_mut() = header; sample_final.send().map_err(|e| { @@ -420,6 +408,10 @@ impl UTransport for Iceoryx2Transport { } } +mod receiver; + + + #[cfg(test)] mod tests { use super::*; @@ -493,9 +485,75 @@ mod tests { assert_eq!(name, "up/device1/CD/1/4/1000/device1/20/1/1/0"); } + #[cfg(test)] +mod tests { + use super::*; + use std::sync::atomic::{AtomicBool, Ordering}; + use std::time::Duration; + use up_rust::{UMessageBuilder, UPayloadFormat}; + + fn dummy_uuid() -> up_rust::UUID { + up_rust::UUID::build() + } + + fn test_uri(authority: &str, instance: u16, typ: u16, version: u8, resource: u16) -> UUri { + let entity_id = ((instance as u32) << 16) | (typ as u32); + UUri::try_from_parts(authority, entity_id, version, resource).unwrap() + } + + #[test] + fn test_publish_service_name() { + let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); + let message = UMessageBuilder::publish(source.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/10AB/0/3/80CD"); + } + + #[test] + fn test_notification_service_name() { + let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); + let sink = test_uri("device1", 0x0000, 0x30EF, 0x04, 0x0000); + let message = UMessageBuilder::notification(source.clone(), sink.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/10AB/0/3/80CD/device1/30EF/0/4/0"); + } + + #[test] + fn test_rpc_request_service_name() { + let sink = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); + let reply_to = test_uri("device1", 0x0000, 0x0001, 0x01, 0x0000); + + let message = UMessageBuilder::request(sink.clone(), reply_to, 1000) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/CD/0/4/B"); + } + + #[test] + fn test_rpc_response_service_name() { + let source = test_uri("device1", 0x0001, 0x0020, 0x01, 0x0000); + let sink = test_uri("device1", 0x0001, 0x00CD, 0x04, 0x1000); + let uuid = dummy_uuid(); + + let message = UMessageBuilder::response(source.clone(), uuid, sink.clone()) + .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); + assert_eq!(name, "up/device1/CD/1/4/1000/device1/20/1/1/0"); + } + #[test] fn test_missing_uri_error() { - let message = UMessage::new(); // no source or sink + let message = UMessage::new(); let result = Iceoryx2Transport::compute_service_name(&message); assert!(result.is_err()); @@ -510,8 +568,11 @@ mod tests { #[async_trait::async_trait] impl UListener for TestListener { - async fn on_receive(&self, _message: UMessage) { + async fn on_receive(&self, message: UMessage) { println!("TestListener received a message!"); + if let Some(payload) = message.payload { + println!("Received payload: {:?}", payload); + } self.received.store(true, Ordering::SeqCst); } } @@ -529,15 +590,9 @@ mod tests { .await .unwrap(); - // Give a moment for registration to complete tokio::time::sleep(Duration::from_millis(100)).await; - let data = TransmissionData { - x: 1, - y: 2, - funky: 3.14, - }; - let payload_bytes = data.to_bytes(); + let payload_bytes = vec![1, 2, 3, 4]; let msg = UMessageBuilder::publish(source_uri) .build_with_payload(payload_bytes, UPayloadFormat::UPAYLOAD_FORMAT_RAW) @@ -545,7 +600,6 @@ mod tests { transport.send(msg).await.unwrap(); - // Give a moment for the message to be received tokio::time::sleep(Duration::from_millis(200)).await; assert!(received.load(Ordering::SeqCst)); @@ -559,7 +613,11 @@ mod tests { #[async_trait::async_trait] impl UListener for TestListener { - async fn on_receive(&self, _message: UMessage) { + async fn on_receive(&self, message: UMessage) { + println!("TestListener received a message!"); + if let Some(payload) = message.payload { + println!("Received payload: {:?}", payload); + } self.received.store(true, Ordering::SeqCst); } } @@ -581,15 +639,9 @@ mod tests { .await .unwrap(); - // Give a moment for unregistration to complete tokio::time::sleep(Duration::from_millis(100)).await; - let data = TransmissionData { - x: 1, - y: 2, - funky: 3.14, - }; - let payload_bytes = data.to_bytes(); + let payload_bytes = vec![1, 2, 3, 4]; let msg = UMessageBuilder::publish(source_uri) .build_with_payload(payload_bytes, UPayloadFormat::UPAYLOAD_FORMAT_RAW) @@ -597,13 +649,11 @@ mod tests { transport.send(msg).await.unwrap(); - // Give a moment for the message to be (or not be) received tokio::time::sleep(Duration::from_millis(200)).await; assert!(!received.load(Ordering::SeqCst)); - // Give a moment for the service to be deallocated tokio::time::sleep(Duration::from_millis(100)).await; } } -mod receiver; \ No newline at end of file +} \ No newline at end of file diff --git a/src/raw_bytes.rs b/src/raw_bytes.rs new file mode 100644 index 0000000..7b22a47 --- /dev/null +++ b/src/raw_bytes.rs @@ -0,0 +1,24 @@ +use iceoryx2::prelude::*; + +/// A minimal wrapper to hold raw byte payloads for Iceoryx2. +/// +/// Iceoryx2 requires payload types to implement ZeroCopySend. +/// This struct makes raw Vec compatible. +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RawBytes { + pub data: Vec, +} + +unsafe impl ZeroCopySend for RawBytes {} + +impl RawBytes { + /// Converts this RawBytes into a Vec. + pub fn to_bytes(&self) -> Vec { + self.data.clone() + } + + /// Creates a RawBytes struct from a Vec. + pub fn from_bytes(bytes: Vec) -> Self { + Self { data: bytes } + } +} diff --git a/src/receiver.rs b/src/receiver.rs index ec1cf8a..0478e66 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -17,8 +17,6 @@ use env_logger; use std::sync::Once; - - static INIT_LOGGER: Once = Once::new(); fn init_logger() { @@ -27,8 +25,6 @@ fn init_logger() { }); } - - const MESSAGE_DATA: &str = "Hello World!"; pub struct Receiver{ @@ -37,21 +33,20 @@ pub struct Receiver{ } impl Receiver{ - pub fn new(expected: UMessage,notify: Arc) -> Self{ - Self{ expected,notify - } + pub fn new(expected: UMessage, notify: Arc) -> Self { + Self { expected, notify } } } #[async_trait] impl UListener for Receiver{ - async fn on_receive(&self,message:UMessage)->(){ - if let Some(payload)=&message.payload{ - println!("Receieved Message ID: {:#?}", message.id()); + async fn on_receive(&self, message: UMessage) { + if let Some(payload) = &message.payload { + println!("Received Message ID: {:#?}", message.id()); if let (Some(expected_payload), Some(actual_payload)) = (&self.expected.payload, &message.payload) { - assert_eq!(expected_payload, actual_payload); + assert_eq!(expected_payload, actual_payload); } else { - panic!("Missing payloads in either expected or actual message"); + panic!("Missing payloads in either expected or actual message"); } self.notify.notify_one(); } @@ -65,12 +60,11 @@ async fn register_listener_and_send( sink_filter: Option<&UUri>, ) -> Result<(), Box> { init_logger(); - let source_uri= UUri::try_from_parts(authority, 0xABC, 1, 0)?; + let source_uri = UUri::try_from_parts(authority, 0xABC, 1, 0)?; let transport = Iceoryx2Transport::new().unwrap(); let notify = Arc::new(Notify::new()); - let receiver=Arc::new(Receiver::new(umessage.clone(),notify.clone())); + let receiver = Arc::new(Receiver::new(umessage.clone(), notify.clone())); - // [itest->dsn~supported-message-delivery-methods~1] transport .register_listener(source_filter, sink_filter, receiver) .await.unwrap(); @@ -92,7 +86,6 @@ async fn register_listener_and_send( } #[test_case::test_case("vehicle1", 12_000, "//vehicle1/10A10B/1/CA5D", "//vehicle1/10A10B/1/CA5D"; "specific source filter")] -// [utest->dsn~up-attributes-ttl~1] #[test_case::test_case("vehicle1", 0, "/D5A/3/9999", "//vehicle1/D5A/3/FFFF"; "source filter with wildcard resource ID")] #[test_case::test_case("vehicle1", 12_000, "//vehicle1/70222/2/8001", "//*/FFFF0222/2/8001"; "source filter with wildcard authority and service instance ID")] #[tokio::test(flavor = "multi_thread")] @@ -104,17 +97,13 @@ async fn test_publish_gets_to_listener( ) -> Result<(), Box> { let topic = UUri::from_str(topic_uri)?; let source_filter = topic.clone(); - let data = TransmissionData { x: 1, y: 2, funky: 3.14 }; - let payload = data.to_bytes(); + let payload = vec![1, 2, 3, 4]; // ✅ Raw byte array instead of TransmissionData let umessage = UMessageBuilder::publish(topic.clone()) .with_priority(up_rust::UPriority::UPRIORITY_CS5) .with_traceparent("traceparent") .with_ttl(ttl) - .build_with_payload(payload, UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; + .build_with_payload(payload, UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; register_listener_and_send(authority, umessage, &source_filter, None).await } - - - diff --git a/src/transmission_data.rs b/src/transmission_data.rs index 76488ba..d2e2c5e 100644 --- a/src/transmission_data.rs +++ b/src/transmission_data.rs @@ -10,6 +10,8 @@ // // SPDX-License-Identifier: Apache-2.0 OR MIT + +/* use iceoryx2::prelude::*; use up_rust::{UCode, UMessage, UStatus}; @@ -58,3 +60,5 @@ impl TransmissionData { Self::from_bytes(payload.to_vec()) } } + +*/ \ No newline at end of file From 6e8524c527edd2a6338cd0ee9301806a5365555b Mon Sep 17 00:00:00 2001 From: kwarraich Date: Tue, 8 Jul 2025 15:51:27 -0500 Subject: [PATCH 23/42] adding a test case to make sure mockUListener works --- src/receiver.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/receiver.rs b/src/receiver.rs index 0478e66..d7afb8c 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -8,7 +8,7 @@ use tokio::sync::Notify; use log::info; use up_rust::{ - UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, + UAttributes, MockUListener, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, UStatus, UTransport, UUri, }; use std::str::FromStr; @@ -107,3 +107,20 @@ async fn test_publish_gets_to_listener( register_listener_and_send(authority, umessage, &source_filter, None).await } + + +#[tokio::test] +async fn test_mock_listener() { + let mut listener = MockUListener::new(); + + // Set expectation: simply print and return () + listener + .expect_on_receive() + .returning(|_message| { + println!("Mock listener called!"); + }); + + let message = UMessage::new(); + + listener.on_receive(message).await; +} \ No newline at end of file From 1a0d554f6cc3a960a7b778335d31c13bf1532b27 Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Wed, 9 Jul 2025 02:49:01 +0530 Subject: [PATCH 24/42] testing unregister in receiver --- src/receiver.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/receiver.rs b/src/receiver.rs index 0478e66..9c63419 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -8,7 +8,7 @@ use tokio::sync::Notify; use log::info; use up_rust::{ - UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, + MockUListener,UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, UStatus, UTransport, UUri, }; use std::str::FromStr; @@ -107,3 +107,49 @@ async fn test_publish_gets_to_listener( register_listener_and_send(authority, umessage, &source_filter, None).await } + +#[tokio::test(flavor = "multi_thread")] +async fn test_unregister_listener_stops_processing_of_messages() { + let transport = Iceoryx2Transport::new().unwrap(); + let message_received = Arc::new(Notify::new()); + let message_received_barrier = message_received.clone(); + let mut listener = MockUListener::new(); + listener.expect_on_receive().returning(move |_msg| { + message_received.notify_one(); + }); + + let listener_to_register = Arc::new(listener); + let msg = + UMessageBuilder::publish(UUri::from_str("//vehicle/123/1/9000").expect("invalid topic")) + .build() + .expect("failed to create message"); + + // [utest->dsn~utransport-registerlistener-start-invoking-listeners~1] + assert!(transport + .register_listener(&UUri::any(), None, listener_to_register.clone()) + .await + .is_ok()); + + // first message is expected to be processed by listener + assert!(transport.send(msg.clone()).await.is_ok()); + assert!( + tokio::time::timeout(Duration::from_secs(3), message_received_barrier.notified()) + .await + .is_ok() + ); + + // [utest->dsn~utransport-unregisterlistener-stop-invoking-listeners~1] + // after unregistering the listener, + assert!(transport + .unregister_listener(&UUri::any(), None, listener_to_register) + .await + .is_ok()); + // no further messages should be processed + assert!( + tokio::time::timeout(Duration::from_secs(3), message_received_barrier.notified()) + .await + .is_err(), + "Expected no further messages to be processed after unregistering the listener" + ); +} + From ed4cb86e760d4cb22c21ff80421dae910de65840 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Tue, 8 Jul 2025 16:45:57 -0500 Subject: [PATCH 25/42] added a test case --- src/lib.rs | 177 +----------------------------------------------- src/receiver.rs | 42 ++++++------ 2 files changed, 25 insertions(+), 194 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b4d8e0c..d6070e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -232,7 +232,8 @@ impl Iceoryx2Transport { let mut new_umessage = UMessage::new(); new_umessage.attributes = MessageField::some(UAttributes::from(sample.user_header())); - new_umessage.payload = Some(sample.payload().to_bytes().into()); + new_umessage.payload = + Some(sample.payload().to_bytes().into()); let listener_clone = listener.clone(); tokio::spawn(async move { listener_clone.on_receive(new_umessage).await; @@ -410,83 +411,9 @@ impl UTransport for Iceoryx2Transport { mod receiver; - - #[cfg(test)] mod tests { - use super::*; - use std::sync::atomic::{AtomicBool, Ordering}; - use std::time::Duration; - use up_rust::{UMessageBuilder, UPayloadFormat}; - - // fn dummy_uuid() -> up_rust::UUID { - // // let uuid = UUID::new(); - // let uuid = up_rust::UUID::new(); - // up_rust::UUID::try_from(uuid).expect("Valid UUID conversion") - // } - fn dummy_uuid() -> up_rust::UUID { - up_rust::UUID::build() - } - - // Helper function to create a test URI - fn test_uri(authority: &str, instance: u16, typ: u16, version: u8, resource: u16) -> UUri { - let entity_id = ((instance as u32) << 16) | (typ as u32); - UUri::try_from_parts(authority, entity_id, version, resource).unwrap() - } - - #[test] - fn test_publish_service_name() { - let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); - let message = UMessageBuilder::publish(source.clone()) - .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); - assert_eq!(name, "up/device1/10AB/0/3/80CD"); - } - - #[test] - fn test_notification_service_name() { - let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); - let sink = test_uri("device1", 0x0000, 0x30EF, 0x04, 0x0000); - let message = UMessageBuilder::notification(source.clone(), sink.clone()) - .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); - assert_eq!(name, "up/device1/10AB/0/3/80CD/device1/30EF/0/4/0"); - } - - #[test] - fn test_rpc_request_service_name() { - let sink = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); - let reply_to = test_uri("device1", 0x0000, 0x0001, 0x01, 0x0000); // Dummy reply URI - - let message = UMessageBuilder::request(sink.clone(), reply_to, 1000) - .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); - assert_eq!(name, "up/device1/CD/0/4/B"); - } - - #[test] - fn test_rpc_response_service_name() { - let source = test_uri("device1", 0x0001, 0x0020, 0x01, 0x0000); - let sink = test_uri("device1", 0x0001, 0x00CD, 0x04, 0x1000); - let uuid = dummy_uuid(); - - let message = UMessageBuilder::response(source.clone(), uuid, sink.clone()) - .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let name = Iceoryx2Transport::compute_service_name(&message).unwrap(); - - assert_eq!(name, "up/device1/CD/1/4/1000/device1/20/1/1/0"); - } - - #[cfg(test)] -mod tests { + // (keep your tests unchanged, they're correct!) use super::*; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; @@ -528,7 +455,6 @@ mod tests { fn test_rpc_request_service_name() { let sink = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); let reply_to = test_uri("device1", 0x0000, 0x0001, 0x01, 0x0000); - let message = UMessageBuilder::request(sink.clone(), reply_to, 1000) .build_with_payload(vec![], UPayloadFormat::UPAYLOAD_FORMAT_RAW) .unwrap(); @@ -559,101 +485,4 @@ mod tests { assert!(result.is_err()); assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); } - - #[tokio::test] - async fn test_register_listener_and_receive() { - struct TestListener { - received: Arc, - } - - #[async_trait::async_trait] - impl UListener for TestListener { - async fn on_receive(&self, message: UMessage) { - println!("TestListener received a message!"); - if let Some(payload) = message.payload { - println!("Received payload: {:?}", payload); - } - self.received.store(true, Ordering::SeqCst); - } - } - - let transport = Iceoryx2Transport::new().unwrap(); - let source_uri = test_uri("test_authority", 0, 1, 1, 0x8001); - - let received = Arc::new(AtomicBool::new(false)); - let listener = Arc::new(TestListener { - received: received.clone(), - }); - - transport - .register_listener(&source_uri, None, listener) - .await - .unwrap(); - - tokio::time::sleep(Duration::from_millis(100)).await; - - let payload_bytes = vec![1, 2, 3, 4]; - - let msg = UMessageBuilder::publish(source_uri) - .build_with_payload(payload_bytes, UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - transport.send(msg).await.unwrap(); - - tokio::time::sleep(Duration::from_millis(200)).await; - - assert!(received.load(Ordering::SeqCst)); - } - - #[tokio::test] - async fn test_unregister_listener() { - struct TestListener { - received: Arc, - } - - #[async_trait::async_trait] - impl UListener for TestListener { - async fn on_receive(&self, message: UMessage) { - println!("TestListener received a message!"); - if let Some(payload) = message.payload { - println!("Received payload: {:?}", payload); - } - self.received.store(true, Ordering::SeqCst); - } - } - - let transport = Iceoryx2Transport::new().unwrap(); - let source_uri = test_uri("test_authority", 0, 1, 1, 0x8002); - - let received = Arc::new(AtomicBool::new(false)); - let listener = Arc::new(TestListener { - received: received.clone(), - }); - - transport - .register_listener(&source_uri, None, listener.clone()) - .await - .unwrap(); - transport - .unregister_listener(&source_uri, None, listener) - .await - .unwrap(); - - tokio::time::sleep(Duration::from_millis(100)).await; - - let payload_bytes = vec![1, 2, 3, 4]; - - let msg = UMessageBuilder::publish(source_uri) - .build_with_payload(payload_bytes, UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - transport.send(msg).await.unwrap(); - - tokio::time::sleep(Duration::from_millis(200)).await; - - assert!(!received.load(Ordering::SeqCst)); - - tokio::time::sleep(Duration::from_millis(100)).await; - } } -} \ No newline at end of file diff --git a/src/receiver.rs b/src/receiver.rs index d7afb8c..7134890 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -3,12 +3,11 @@ use std::sync::Arc; use std::time::Duration; use async_trait::async_trait; -use bytes::Bytes; use tokio::sync::Notify; use log::info; use up_rust::{ - UAttributes, MockUListener, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, + MockUListener, UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, UStatus, UTransport, UUri, }; use std::str::FromStr; @@ -27,23 +26,25 @@ fn init_logger() { const MESSAGE_DATA: &str = "Hello World!"; -pub struct Receiver{ +pub struct Receiver { expected: UMessage, notify: Arc, } -impl Receiver{ +impl Receiver { pub fn new(expected: UMessage, notify: Arc) -> Self { Self { expected, notify } } } #[async_trait] -impl UListener for Receiver{ - async fn on_receive(&self, message: UMessage) { +impl UListener for Receiver { + async fn on_receive(&self, message: UMessage) -> () { if let Some(payload) = &message.payload { println!("Received Message ID: {:#?}", message.id()); - if let (Some(expected_payload), Some(actual_payload)) = (&self.expected.payload, &message.payload) { + if let (Some(expected_payload), Some(actual_payload)) = + (&self.expected.payload, &message.payload) + { assert_eq!(expected_payload, actual_payload); } else { panic!("Missing payloads in either expected or actual message"); @@ -64,10 +65,11 @@ async fn register_listener_and_send( let transport = Iceoryx2Transport::new().unwrap(); let notify = Arc::new(Notify::new()); let receiver = Arc::new(Receiver::new(umessage.clone(), notify.clone())); - + transport .register_listener(source_filter, sink_filter, receiver) - .await.unwrap(); + .await + .unwrap(); // Send UMessage info!( @@ -76,13 +78,14 @@ async fn register_listener_and_send( umessage.type_unchecked().to_cloudevent_type() ); transport.send(umessage).await?; - Ok( - tokio::time::timeout(Duration::from_secs(3), notify.notified()) - .await - .map_err(|_| { - UStatus::fail_with_code(UCode::DEADLINE_EXCEEDED, "did not receive message in time") - })?, - ) + Ok(tokio::time::timeout(Duration::from_secs(3), notify.notified()) + .await + .map_err(|_| { + UStatus::fail_with_code( + UCode::DEADLINE_EXCEEDED, + "did not receive message in time", + ) + })?) } #[test_case::test_case("vehicle1", 12_000, "//vehicle1/10A10B/1/CA5D", "//vehicle1/10A10B/1/CA5D"; "specific source filter")] @@ -97,7 +100,8 @@ async fn test_publish_gets_to_listener( ) -> Result<(), Box> { let topic = UUri::from_str(topic_uri)?; let source_filter = topic.clone(); - let payload = vec![1, 2, 3, 4]; // ✅ Raw byte array instead of TransmissionData + + let payload = vec![1, 2, 3, 4, 5]; let umessage = UMessageBuilder::publish(topic.clone()) .with_priority(up_rust::UPriority::UPRIORITY_CS5) @@ -108,12 +112,10 @@ async fn test_publish_gets_to_listener( register_listener_and_send(authority, umessage, &source_filter, None).await } - #[tokio::test] async fn test_mock_listener() { let mut listener = MockUListener::new(); - // Set expectation: simply print and return () listener .expect_on_receive() .returning(|_message| { @@ -123,4 +125,4 @@ async fn test_mock_listener() { let message = UMessage::new(); listener.on_receive(message).await; -} \ No newline at end of file +} From 73456ff5dfe45fcf895f1910dfb1b34148c61799 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Wed, 9 Jul 2025 19:04:30 -0500 Subject: [PATCH 26/42] adding some more tests and pushing the mockUListener into the test block --- src/lib.rs | 110 +++++++++++++++++++++++++++++++++++++++++++++++- src/receiver.rs | 3 +- 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d6070e3..d91d309 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -413,11 +413,10 @@ mod receiver; #[cfg(test)] mod tests { - // (keep your tests unchanged, they're correct!) use super::*; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; - use up_rust::{UMessageBuilder, UPayloadFormat}; + use up_rust::{UMessageBuilder, MockUListener, UPayloadFormat}; fn dummy_uuid() -> up_rust::UUID { up_rust::UUID::build() @@ -485,4 +484,111 @@ mod tests { assert!(result.is_err()); assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); } + + #[tokio::test] + async fn test_send_message() { + let transport = Iceoryx2Transport::new().unwrap(); + + let source = test_uri("device1", 0x0000, 0x1234, 0x01, 0x8000); + let msg = UMessageBuilder::publish(source) + .build_with_payload(vec![1, 2, 3], UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + let res = transport.send(msg).await; + assert!(res.is_ok(), "send() returned error: {:?}", res); + } + + #[tokio::test] +async fn test_register_listener_with_mockUListener() { + let transport = Iceoryx2Transport::new().unwrap(); + + let mut listener = MockUListener::new(); + + listener + .expect_on_receive() + .returning(|msg| { + println!("Mock listener called with payload: {:?}", msg.payload); + }); + + let topic = test_uri("deviceX", 0x0000, 0x1234, 0x01, 0x8000); + + transport + .register_listener(&topic, None, Arc::new(listener)) + .await + .unwrap(); + + let msg = UMessageBuilder::publish(topic.clone()) + .build_with_payload(b"hello".to_vec(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + transport.send(msg).await.unwrap(); + + // Sleep briefly to let the background task run. + tokio::time::sleep(std::time::Duration::from_millis(50)).await; +} + +#[tokio::test] +async fn test_unregister_listener_with_mock() { + let transport = Iceoryx2Transport::new().unwrap(); + + // Create the mock listener + let mut listener = MockUListener::new(); + + // Track how many times on_receive is called + let call_counter = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0)); + let counter_clone = call_counter.clone(); + + listener + .expect_on_receive() + .returning(move |_msg| { + counter_clone.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + }); + + let listener_arc = Arc::new(listener); + + let topic = test_uri("deviceB", 0x0000, 0x2222, 0x02, 0x8000); + + // Register the listener + transport + .register_listener(&topic, None, listener_arc.clone()) + .await + .unwrap(); + + // Send first message + let first = UMessageBuilder::publish(topic.clone()) + .build_with_payload(b"first".to_vec(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + transport.send(first).await.unwrap(); + + // Give time for delivery + tokio::time::sleep(std::time::Duration::from_millis(50)).await; + + // Verify the listener fired once + assert_eq!(call_counter.load(std::sync::atomic::Ordering::SeqCst), 1); + + // Now unregister + transport + .unregister_listener(&topic, None, listener_arc.clone()) + .await + .unwrap(); + + // Send second message + let second = UMessageBuilder::publish(topic.clone()) + .build_with_payload(b"second".to_vec(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) + .unwrap(); + + transport.send(second).await.unwrap(); + + // Wait a bit in case it would fire + tokio::time::sleep(std::time::Duration::from_millis(50)).await; + + // Check that no new calls happened + assert_eq!( + call_counter.load(std::sync::atomic::Ordering::SeqCst), + 1, + "Listener should not fire after unregister" + ); +} + } diff --git a/src/receiver.rs b/src/receiver.rs index 7134890..6ab1bee 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -7,7 +7,7 @@ use tokio::sync::Notify; use log::info; use up_rust::{ - MockUListener, UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, + UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, UStatus, UTransport, UUri, }; use std::str::FromStr; @@ -114,6 +114,7 @@ async fn test_publish_gets_to_listener( #[tokio::test] async fn test_mock_listener() { + use up_rust::MockUListener; let mut listener = MockUListener::new(); listener From 3aa458238319350ae5cee9759b273b8096a75bf3 Mon Sep 17 00:00:00 2001 From: Noella Horo Date: Thu, 10 Jul 2025 08:44:06 +0530 Subject: [PATCH 27/42] fixed uuri wildcard logic and made RawBytes compatible with iceoryx2 memory safe structures --- Cargo.lock | 1 + Cargo.toml | 1 + src/lib.rs | 121 ++++------------------------------------------- src/raw_bytes.rs | 21 +++++--- 4 files changed, 27 insertions(+), 117 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f04b40..a4fdb3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1381,6 +1381,7 @@ dependencies = [ "bytes", "env_logger", "iceoryx2", + "iceoryx2-bb-container", "log", "once_cell", "protobuf", diff --git a/Cargo.toml b/Cargo.toml index 6f6c533..5433569 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ log = "0.4.27" env_logger = "0.11.8" once_cell = "1.18.0" uuid = { version = "1", features = ["v4"] } +iceoryx2-bb-container = "0.6.1" [dev-dependencies] diff --git a/src/lib.rs b/src/lib.rs index d91d309..f7ab67a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,8 +48,13 @@ impl Iceoryx2Transport { } fn encode_uuri_segments(uuri: &UUri) -> Vec { + let authority = if uuri.authority_name == "*" { + "wildcard".to_string() + } else { + uuri.authority_name.clone() + }; vec![ - uuri.authority_name.clone(), + authority, Self::encode_hex_no_leading_zeros(uuri.uentity_type_id() as u32), Self::encode_hex_no_leading_zeros(uuri.uentity_instance_id() as u32), Self::encode_hex_no_leading_zeros(uuri.uentity_major_version() as u32), @@ -323,7 +328,7 @@ impl Iceoryx2Transport { message: UMessage, ) -> Result<(), UStatus> { let payload_bytes = message.payload.clone().unwrap_or_default().to_vec(); - let raw_payload = RawBytes::from_bytes(payload_bytes); + let raw_payload = RawBytes::from_bytes(&payload_bytes); let header = CustomHeader::from_message(&message)?; let sample = publisher.loan_uninit().map_err(|e| { @@ -413,10 +418,11 @@ mod receiver; #[cfg(test)] mod tests { + // (keep your tests unchanged, they're correct!) use super::*; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; - use up_rust::{UMessageBuilder, MockUListener, UPayloadFormat}; + use up_rust::{UMessageBuilder, UPayloadFormat}; fn dummy_uuid() -> up_rust::UUID { up_rust::UUID::build() @@ -484,111 +490,4 @@ mod tests { assert!(result.is_err()); assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); } - - #[tokio::test] - async fn test_send_message() { - let transport = Iceoryx2Transport::new().unwrap(); - - let source = test_uri("device1", 0x0000, 0x1234, 0x01, 0x8000); - let msg = UMessageBuilder::publish(source) - .build_with_payload(vec![1, 2, 3], UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - let res = transport.send(msg).await; - assert!(res.is_ok(), "send() returned error: {:?}", res); - } - - #[tokio::test] -async fn test_register_listener_with_mockUListener() { - let transport = Iceoryx2Transport::new().unwrap(); - - let mut listener = MockUListener::new(); - - listener - .expect_on_receive() - .returning(|msg| { - println!("Mock listener called with payload: {:?}", msg.payload); - }); - - let topic = test_uri("deviceX", 0x0000, 0x1234, 0x01, 0x8000); - - transport - .register_listener(&topic, None, Arc::new(listener)) - .await - .unwrap(); - - let msg = UMessageBuilder::publish(topic.clone()) - .build_with_payload(b"hello".to_vec(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - transport.send(msg).await.unwrap(); - - // Sleep briefly to let the background task run. - tokio::time::sleep(std::time::Duration::from_millis(50)).await; -} - -#[tokio::test] -async fn test_unregister_listener_with_mock() { - let transport = Iceoryx2Transport::new().unwrap(); - - // Create the mock listener - let mut listener = MockUListener::new(); - - // Track how many times on_receive is called - let call_counter = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0)); - let counter_clone = call_counter.clone(); - - listener - .expect_on_receive() - .returning(move |_msg| { - counter_clone.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - }); - - let listener_arc = Arc::new(listener); - - let topic = test_uri("deviceB", 0x0000, 0x2222, 0x02, 0x8000); - - // Register the listener - transport - .register_listener(&topic, None, listener_arc.clone()) - .await - .unwrap(); - - // Send first message - let first = UMessageBuilder::publish(topic.clone()) - .build_with_payload(b"first".to_vec(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - transport.send(first).await.unwrap(); - - // Give time for delivery - tokio::time::sleep(std::time::Duration::from_millis(50)).await; - - // Verify the listener fired once - assert_eq!(call_counter.load(std::sync::atomic::Ordering::SeqCst), 1); - - // Now unregister - transport - .unregister_listener(&topic, None, listener_arc.clone()) - .await - .unwrap(); - - // Send second message - let second = UMessageBuilder::publish(topic.clone()) - .build_with_payload(b"second".to_vec(), UPayloadFormat::UPAYLOAD_FORMAT_RAW) - .unwrap(); - - transport.send(second).await.unwrap(); - - // Wait a bit in case it would fire - tokio::time::sleep(std::time::Duration::from_millis(50)).await; - - // Check that no new calls happened - assert_eq!( - call_counter.load(std::sync::atomic::Ordering::SeqCst), - 1, - "Listener should not fire after unregister" - ); -} - -} +} \ No newline at end of file diff --git a/src/raw_bytes.rs b/src/raw_bytes.rs index 7b22a47..537f9cc 100644 --- a/src/raw_bytes.rs +++ b/src/raw_bytes.rs @@ -1,12 +1,17 @@ use iceoryx2::prelude::*; - +use iceoryx2_bb_container::{ + vec::FixedSizeVec, + byte_string::FixedSizeByteString, +}; /// A minimal wrapper to hold raw byte payloads for Iceoryx2. /// /// Iceoryx2 requires payload types to implement ZeroCopySend. /// This struct makes raw Vec compatible. +const MAX_RAW_BYTES_SIZE: usize = 4096; #[derive(Debug, Clone, PartialEq, Default)] +#[repr(C)] pub struct RawBytes { - pub data: Vec, + pub data: FixedSizeVec, } unsafe impl ZeroCopySend for RawBytes {} @@ -14,11 +19,15 @@ unsafe impl ZeroCopySend for RawBytes {} impl RawBytes { /// Converts this RawBytes into a Vec. pub fn to_bytes(&self) -> Vec { - self.data.clone() + self.data.as_slice().to_vec() } /// Creates a RawBytes struct from a Vec. - pub fn from_bytes(bytes: Vec) -> Self { - Self { data: bytes } + pub fn from_bytes(bytes: &[u8]) -> Self { + let mut data = FixedSizeVec::new(); + for &byte in bytes { + let _ok = data.push(byte); + } + RawBytes { data } } -} +} \ No newline at end of file From e36dc085109713d118e0d55b2d7dd808876f98e6 Mon Sep 17 00:00:00 2001 From: Noella Horo Date: Thu, 10 Jul 2025 09:19:53 +0530 Subject: [PATCH 28/42] modified cargo.toml to make test-utils availale in dependencies --- Cargo.toml | 5 ++- src/receiver.rs | 92 +++++++++++++++++++++++++++++++------------------ 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6f6c533..1a76b16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2024" [dependencies] -up-rust = "0.5" +up-rust = { version = "0.5.0", features = ["test-util"] } iceoryx2 = "0.6.1" async-trait = "0.1" protobuf = "3.7.2" @@ -17,6 +17,5 @@ once_cell = "1.18.0" uuid = { version = "1", features = ["v4"] } -[dev-dependencies] -up-rust = { version = "0.5.0", features = ["test-util"] } + diff --git a/src/receiver.rs b/src/receiver.rs index 9c63419..971a947 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -110,46 +110,70 @@ async fn test_publish_gets_to_listener( #[tokio::test(flavor = "multi_thread")] async fn test_unregister_listener_stops_processing_of_messages() { - let transport = Iceoryx2Transport::new().unwrap(); - let message_received = Arc::new(Notify::new()); - let message_received_barrier = message_received.clone(); - let mut listener = MockUListener::new(); - listener.expect_on_receive().returning(move |_msg| { - message_received.notify_one(); + use std::sync::atomic::{AtomicUsize, Ordering}; + use std::time::Duration; + + let transport = Iceoryx2Transport::new().unwrap(); + + let first_received = Arc::new(Notify::new()); + let second_received = Arc::new(Notify::new()); + + struct TestListener { + first_barrier: Arc, + second_barrier: Arc, + hit_count: AtomicUsize, + } + + #[async_trait::async_trait] + impl UListener for TestListener { + async fn on_receive(&self, _msg: UMessage) { + let count = self.hit_count.fetch_add(1, Ordering::SeqCst); + if count == 0 { + self.first_barrier.notify_one(); + } else { + self.second_barrier.notify_one(); + } + } + } + + let listener = Arc::new(TestListener { + first_barrier: first_received.clone(), + second_barrier: second_received.clone(), + hit_count: AtomicUsize::new(0), }); - let listener_to_register = Arc::new(listener); - let msg = - UMessageBuilder::publish(UUri::from_str("//vehicle/123/1/9000").expect("invalid topic")) - .build() - .expect("failed to create message"); + let uri = UUri::from_str("//vehicle/123/1/9000").unwrap(); + let msg = UMessageBuilder::publish(uri.clone()) + .build() + .expect("failed to build"); + + // Register + transport.register_listener(&UUri::any(), None, listener.clone()).await.unwrap(); + + // Let subscriber start + tokio::time::sleep(Duration::from_millis(200)).await; - // [utest->dsn~utransport-registerlistener-start-invoking-listeners~1] - assert!(transport - .register_listener(&UUri::any(), None, listener_to_register.clone()) - .await - .is_ok()); + // Send first message + transport.send(msg.clone()).await.unwrap(); - // first message is expected to be processed by listener - assert!(transport.send(msg.clone()).await.is_ok()); + // Wait for first message to be received assert!( - tokio::time::timeout(Duration::from_secs(3), message_received_barrier.notified()) - .await - .is_ok() + tokio::time::timeout(Duration::from_secs(3), first_received.notified()).await.is_ok(), + "Listener did not receive the first message" ); - // [utest->dsn~utransport-unregisterlistener-stop-invoking-listeners~1] - // after unregistering the listener, - assert!(transport - .unregister_listener(&UUri::any(), None, listener_to_register) - .await - .is_ok()); - // no further messages should be processed + // Unregister + transport.unregister_listener(&UUri::any(), None, listener).await.unwrap(); + + // Small delay to make sure unsubscribe has taken effect + tokio::time::sleep(Duration::from_millis(100)).await; + + // Send again + transport.send(msg).await.unwrap(); + + // Confirm second message is NOT received assert!( - tokio::time::timeout(Duration::from_secs(3), message_received_barrier.notified()) - .await - .is_err(), - "Expected no further messages to be processed after unregistering the listener" + tokio::time::timeout(Duration::from_secs(3), second_received.notified()).await.is_err(), + "Expected no second message after unregister" ); -} - +} \ No newline at end of file From bf2f6081da4ad2428678a06eddbe0d8280b13445 Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Thu, 10 Jul 2025 21:04:09 +0530 Subject: [PATCH 29/42] these tests pass without wildcard URIs so replaced Uuri::any with the exact definition of the uri being sent --- src/receiver.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/receiver.rs b/src/receiver.rs index 971a947..4754790 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -128,6 +128,7 @@ async fn test_unregister_listener_stops_processing_of_messages() { impl UListener for TestListener { async fn on_receive(&self, _msg: UMessage) { let count = self.hit_count.fetch_add(1, Ordering::SeqCst); + println!("Received a message, count = {}", count); if count == 0 { self.first_barrier.notify_one(); } else { @@ -147,8 +148,14 @@ async fn test_unregister_listener_stops_processing_of_messages() { .build() .expect("failed to build"); - // Register - transport.register_listener(&UUri::any(), None, listener.clone()).await.unwrap(); + let mut listener_registered=false; + // Register listener + if transport + .register_listener(&uri, None, listener.clone()).await.is_ok(){ + listener_registered = true; + } + //test if listener was registered + assert!(listener_registered, "Listener was not registered"); // Let subscriber start tokio::time::sleep(Duration::from_millis(200)).await; @@ -163,10 +170,10 @@ async fn test_unregister_listener_stops_processing_of_messages() { ); // Unregister - transport.unregister_listener(&UUri::any(), None, listener).await.unwrap(); + transport.unregister_listener(&uri, None, listener.clone()).await.unwrap(); // Small delay to make sure unsubscribe has taken effect - tokio::time::sleep(Duration::from_millis(100)).await; + tokio::time::sleep(Duration::from_millis(300)).await; // Send again transport.send(msg).await.unwrap(); @@ -176,4 +183,10 @@ async fn test_unregister_listener_stops_processing_of_messages() { tokio::time::timeout(Duration::from_secs(3), second_received.notified()).await.is_err(), "Expected no second message after unregister" ); + // Final assertion to ensure exactly one message was received + assert_eq!( + listener.hit_count.load(Ordering::SeqCst), + 1, + "Listener should only process one message" + ); } \ No newline at end of file From 2f2e4ee5c81fa7f0ff80df73a39c9fc68b0e591b Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 10 Jul 2025 11:39:05 -0500 Subject: [PATCH 30/42] adjusted so the ternimals would send the data and properly with the new genetic data --- src/bin/sender.rs | 12 ++++++++---- src/lib.rs | 11 ++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/bin/sender.rs b/src/bin/sender.rs index 08a4a99..77663ca 100644 --- a/src/bin/sender.rs +++ b/src/bin/sender.rs @@ -20,16 +20,20 @@ async fn main() -> Result<(), Box> { let topic = UUri::from_str("//vehicle_shared/10A10B/1/CA5D")?; let transport = Iceoryx2Transport::new().unwrap(); + let mut payload: Vec = vec![1, 2, 3, 4, 5, 6]; + loop { - // byte array payload - let payload: Vec = vec![1, 2, 3, 4, 5, 6]; + // increment each byte + for b in payload.iter_mut() { + *b = b.wrapping_add(1); + } let umessage = UMessageBuilder::publish(topic.clone()) - .build_with_payload(payload, UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; + .build_with_payload(payload.clone(), UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; transport.send(umessage).await?; - println!("Message sent."); + println!("Message sent. Payload: {:?}", payload); tokio::time::sleep(std::time::Duration::from_secs(1)).await; } diff --git a/src/lib.rs b/src/lib.rs index f7ab67a..1cbd2a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,7 +52,7 @@ impl Iceoryx2Transport { "wildcard".to_string() } else { uuri.authority_name.clone() - }; + }; vec![ authority, Self::encode_hex_no_leading_zeros(uuri.uentity_type_id() as u32), @@ -234,11 +234,13 @@ impl Iceoryx2Transport { while let Some(sample) = subscriber.receive().ok().flatten() { if let Some(listeners) = listeners.get(service_name) { for listener in listeners { + let payload_bytes = sample.payload().to_bytes(); + let mut new_umessage = UMessage::new(); new_umessage.attributes = MessageField::some(UAttributes::from(sample.user_header())); - new_umessage.payload = - Some(sample.payload().to_bytes().into()); + new_umessage.payload = Some(payload_bytes.into()); + let listener_clone = listener.clone(); tokio::spawn(async move { listener_clone.on_receive(new_umessage).await; @@ -418,7 +420,6 @@ mod receiver; #[cfg(test)] mod tests { - // (keep your tests unchanged, they're correct!) use super::*; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; @@ -490,4 +491,4 @@ mod tests { assert!(result.is_err()); assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); } -} \ No newline at end of file +} From 65768ab973d0e9a892a5c5396d11e1a8bb399233 Mon Sep 17 00:00:00 2001 From: kwarraich Date: Thu, 10 Jul 2025 14:11:19 -0500 Subject: [PATCH 31/42] adjusted teh reciving end so it would print in decimal --- src/bin/listener.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bin/listener.rs b/src/bin/listener.rs index b4cefdd..82cf8b5 100644 --- a/src/bin/listener.rs +++ b/src/bin/listener.rs @@ -23,7 +23,11 @@ pub struct Receiver { impl UListener for Receiver { async fn on_receive(&self, message: UMessage) { if let Some(payload) = &message.payload { - println!("Received payload bytes: {:?}", payload); + print!("Received payload bytes (decimal): "); + for byte in payload { + print!("{} ", byte); + } + println!(); } else { println!("Received message with no payload."); } @@ -31,6 +35,7 @@ impl UListener for Receiver { } } + #[tokio::main] async fn main() -> Result<(), Box> { init_logger(); From 6aa08f6d9102fcafc532792f28c1145fab764c91 Mon Sep 17 00:00:00 2001 From: arakabCL Date: Mon, 14 Jul 2025 13:36:19 +0300 Subject: [PATCH 32/42] Removed wildcard support from compute listener matching logic. --- src/lib.rs | 31 ++++++++----------------------- src/receiver.rs | 24 ++++++++++++++++++++---- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1cbd2a1..84d3522 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,13 +48,8 @@ impl Iceoryx2Transport { } fn encode_uuri_segments(uuri: &UUri) -> Vec { - let authority = if uuri.authority_name == "*" { - "wildcard".to_string() - } else { - uuri.authority_name.clone() - }; vec![ - authority, + uuri.authority_name.clone(), Self::encode_hex_no_leading_zeros(uuri.uentity_type_id() as u32), Self::encode_hex_no_leading_zeros(uuri.uentity_instance_id() as u32), Self::encode_hex_no_leading_zeros(uuri.uentity_major_version() as u32), @@ -116,23 +111,13 @@ impl Iceoryx2Transport { Ok(format!("up/{}", join_segments(segments))) } Some(sink) => { - let is_wildcard_entity = source_filter.uentity_type_id() == 0xFFFF - && source_filter.uentity_instance_id() == 0xFFFF; - let is_wildcard_version = source_filter.uentity_major_version() == 0xFF; - let is_wildcard_resource = source_filter.resource_id() == 0xFFFF; - - if is_wildcard_entity && is_wildcard_version && is_wildcard_resource { - let segments = Self::encode_uuri_segments(sink); - Ok(format!("up/{}", join_segments(segments))) - } else { - let source_segments = Self::encode_uuri_segments(source_filter); - let sink_segments = Self::encode_uuri_segments(sink); - Ok(format!( - "up/{}/{}", - join_segments(source_segments), - join_segments(sink_segments) - )) - } + let source_segments = Self::encode_uuri_segments(source_filter); + let sink_segments = Self::encode_uuri_segments(sink); + Ok(format!( + "up/{}/{}", + join_segments(source_segments), + join_segments(sink_segments) + )) } } } diff --git a/src/receiver.rs b/src/receiver.rs index a1765b7..ecb3e13 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -89,8 +89,6 @@ async fn register_listener_and_send( } #[test_case::test_case("vehicle1", 12_000, "//vehicle1/10A10B/1/CA5D", "//vehicle1/10A10B/1/CA5D"; "specific source filter")] -#[test_case::test_case("vehicle1", 0, "/D5A/3/9999", "//vehicle1/D5A/3/FFFF"; "source filter with wildcard resource ID")] -#[test_case::test_case("vehicle1", 12_000, "//vehicle1/70222/2/8001", "//*/FFFF0222/2/8001"; "source filter with wildcard authority and service instance ID")] #[tokio::test(flavor = "multi_thread")] async fn test_publish_gets_to_listener( authority: &str, @@ -99,7 +97,7 @@ async fn test_publish_gets_to_listener( source_filter_uri: &str, ) -> Result<(), Box> { let topic = UUri::from_str(topic_uri)?; - let source_filter = topic.clone(); + let source_filter = UUri::from_str(source_filter_uri)?; let payload = vec![1, 2, 3, 4, 5]; @@ -112,6 +110,24 @@ async fn test_publish_gets_to_listener( register_listener_and_send(authority, umessage, &source_filter, None).await } +#[tokio::test] +async fn test_exact_listener_dispatch() -> Result<(), Box> { + let transport = Iceoryx2Transport::new().unwrap(); + let listener_uri = UUri::from_str("//vehicle1/10A10B/1/CA5D")?; + let matching_message = UMessageBuilder::publish(listener_uri.clone()).build_with_payload(vec![1, 2, 3], UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; + let non_matching_message = UMessageBuilder::publish(UUri::from_str("//vehicle2/10A10B/1/CA5D")?).build_with_payload(vec![4, 5, 6], UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; + + let received_notify = Arc::new(Notify::new()); + let listener = Arc::new(Receiver::new(matching_message.clone(), received_notify.clone())); + + transport.register_listener(&listener_uri, None, listener).await?; + transport.send(non_matching_message).await?; + transport.send(matching_message).await?; + + tokio::time::timeout(Duration::from_secs(1), received_notify.notified()).await?; + Ok(()) +} + #[tokio::test(flavor = "multi_thread")] async fn test_unregister_listener_stops_processing_of_messages() { use std::sync::atomic::{AtomicUsize, Ordering}; @@ -209,4 +225,4 @@ async fn test_mock_listener() { let message = UMessage::new(); listener.on_receive(message).await; -} \ No newline at end of file +} From f74cc6f155ba04cbe8e2ccde5a4632ece1fb9966 Mon Sep 17 00:00:00 2001 From: arakabCL Date: Mon, 14 Jul 2025 13:37:07 +0300 Subject: [PATCH 33/42] Completed wildcard removal from compute listener with tests. From e367b1937d94ab6623b2a56295e38395048c40e5 Mon Sep 17 00:00:00 2001 From: arakabCL Date: Mon, 14 Jul 2025 15:07:33 +0300 Subject: [PATCH 34/42] Updated register with deserialized attributes handling --- src/custom_header.rs | 39 ++++++++++++++++++++++++++------------- src/lib.rs | 31 +++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/custom_header.rs b/src/custom_header.rs index ac0f168..efdd826 100644 --- a/src/custom_header.rs +++ b/src/custom_header.rs @@ -17,26 +17,39 @@ impl CustomHeader { }) } - pub fn from_message(_message: &UMessage) -> Result { - // For now, just default - Ok(Self::default()) + pub fn from_message(message: &UMessage) -> Result { + // Extract basic information from UMessage attributes + let version = if let Some(_attributes) = &message.attributes.0 { + 1 // Use a default version for now + } else { + 1 // Default version + }; + + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_millis() as u64; + + Ok(Self { version, timestamp }) } } // Assuming UAttributes has a field called `fields` which is Vec<(String, String)> // Adjust if your actual UAttributes is different impl From<&CustomHeader> for UAttributes { - fn from(_header: &CustomHeader) -> UAttributes { - let attrs = UAttributes::default(); - - // Hypothetical code: add key-value pairs to attrs - // Replace this with your real API to insert attributes - // For example, if UAttributes has a `fields` Vec<(String, String)>: - // attrs.fields.push(("version".to_string(), header.version.to_string())); - // attrs.fields.push(("timestamp".to_string(), header.timestamp.to_string())); - - // If no such field exists, just return default or implement accordingly + fn from(header: &CustomHeader) -> UAttributes { + let mut attrs = UAttributes::default(); + // Map CustomHeader fields back to UAttributes using available fields + // Based on the error message, available fields are: id, type_, source, sink, priority, etc. + + // Set default values for required fields + attrs.type_ = up_rust::UMessageType::UMESSAGE_TYPE_PUBLISH.into(); + attrs.priority = up_rust::UPriority::UPRIORITY_CS4.into(); + + // Note: version and timestamp information is preserved in the CustomHeader + // but UAttributes doesn't have direct fields for them, so we use defaults + attrs } } diff --git a/src/lib.rs b/src/lib.rs index 84d3522..6283570 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -215,17 +215,24 @@ impl Iceoryx2Transport { } } + // Integrate dispatch: In polling/receive, extract attributes and reconstruct UMessage for (service_name, subscriber) in subscribers.iter() { while let Some(sample) = subscriber.receive().ok().flatten() { if let Some(listeners) = listeners.get(service_name) { for listener in listeners { + // Extract payload bytes let payload_bytes = sample.payload().to_bytes(); + // Reconstruct UMessage with deserialized header to UAttributes let mut new_umessage = UMessage::new(); - new_umessage.attributes = - MessageField::some(UAttributes::from(sample.user_header())); + + // Extract attributes (UAttributes::from(custom_header) - full impl: parse version, deserialize Protobuf) + new_umessage.attributes = MessageField::some(UAttributes::from(sample.user_header())); + + // Attach payload bytes new_umessage.payload = Some(payload_bytes.into()); + // Invoke listener.on_message with reconstructed UMessage let listener_clone = listener.clone(); tokio::spawn(async move { listener_clone.on_receive(new_umessage).await; @@ -257,14 +264,18 @@ impl Iceoryx2Transport { } }; + // Remove from hashmap: listeners.get_mut(&service_name).and_then(|vec| vec.remove(&listener)); if let Some(listener_vec) = listeners.get_mut(&service_name) { listener_vec.retain(|l| !Arc::ptr_eq(l, listener)); + + // If last listener, cleanup subscriber (unsubscribe) if listener_vec.is_empty() { listeners.remove(&service_name); subscribers.remove(&service_name); } } + // Return success if removed (or no-op if listener wasn't found) Ok(()) } @@ -286,23 +297,31 @@ impl Iceoryx2Transport { } }; + // Create subscriber if it doesn't exist for this service_name if !subscribers.contains_key(&service_name) { let service_name_res: Result = service_name.as_str().try_into(); let service = node - .service_builder(&service_name_res.unwrap()) + .service_builder(&service_name_res.map_err(|e| { + UStatus::fail_with_code(UCode::INVALID_ARGUMENT, &format!("Invalid service name: {}", e)) + })?) .publish_subscribe::() .user_header::() .open_or_create() - .expect("Failed to create service"); + .map_err(|e| { + UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to create service: {}", e)) + })?; let subscriber = service .subscriber_builder() .create() - .expect("Failed to create subscriber"); + .map_err(|e| { + UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to create subscriber: {}", e)) + })?; subscribers.insert(service_name.clone(), subscriber); } - listeners.entry(service_name).or_default().push(listener); + // Add listener to hashmap: listeners.entry(service_name).or_insert(Vec::new()).push(listener); + listeners.entry(service_name).or_insert_with(Vec::new).push(listener); Ok(()) } From 533e0345e1fa0a5e46d6145805030736d24d544d Mon Sep 17 00:00:00 2001 From: arakabCL Date: Mon, 14 Jul 2025 15:16:33 +0300 Subject: [PATCH 35/42] Complete wildcard removal and listener functionality improvements Removed all wildcard support from compute listener matching logic and implemented exact URI matching via HashMap lookups. Enhanced register and unregister listener functionality with proper error handling, subscriber creation, and cleanup. Added comprehensive test coverage including race condition fixes and edge cases. All 16 tests passing with robust exact matching behavior for production readiness. --- src/lib.rs | 153 ++++++++++++++++++++++++++++++++++++++++++++++-- src/receiver.rs | 66 +++++++++------------ 2 files changed, 176 insertions(+), 43 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6283570..b9a4aa5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -216,10 +216,19 @@ impl Iceoryx2Transport { } // Integrate dispatch: In polling/receive, extract attributes and reconstruct UMessage - for (service_name, subscriber) in subscribers.iter() { - while let Some(sample) = subscriber.receive().ok().flatten() { - if let Some(listeners) = listeners.get(service_name) { - for listener in listeners { + // Only process subscribers that have active listeners + let active_services: Vec<(String, Vec>)> = listeners + .iter() + .filter(|(service_name, listeners_vec)| { + !listeners_vec.is_empty() && subscribers.contains_key(*service_name) + }) + .map(|(service_name, listeners_vec)| (service_name.clone(), listeners_vec.clone())) + .collect(); + + for (service_name, listeners_to_notify) in active_services { + if let Some(subscriber) = subscribers.get(&service_name) { + while let Some(sample) = subscriber.receive().ok().flatten() { + for listener in &listeners_to_notify { // Extract payload bytes let payload_bytes = sample.payload().to_bytes(); @@ -427,7 +436,7 @@ mod tests { use super::*; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; - use up_rust::{UMessageBuilder, UPayloadFormat}; + use up_rust::{UMessageBuilder, UPayloadFormat, MockUListener}; fn dummy_uuid() -> up_rust::UUID { up_rust::UUID::build() @@ -495,4 +504,138 @@ mod tests { assert!(result.is_err()); assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); } + + #[tokio::test] + async fn test_register_listener_creates_subscriber() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener = Arc::new(MockUListener::new()); + + // Register listener should succeed + let result = transport.register_listener(&uri, None, listener.clone()).await; + assert!(result.is_ok(), "Listener registration should succeed"); + } + + #[tokio::test] + async fn test_register_duplicate_listeners() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener1 = Arc::new(MockUListener::new()); + let listener2 = Arc::new(MockUListener::new()); + + // Register first listener + let result1 = transport.register_listener(&uri, None, listener1.clone()).await; + assert!(result1.is_ok(), "First listener registration should succeed"); + + // Register second listener for same URI (should reuse subscriber) + let result2 = transport.register_listener(&uri, None, listener2.clone()).await; + assert!(result2.is_ok(), "Second listener registration should succeed"); + } + + #[tokio::test] + async fn test_unregister_listener_cleanup() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener = Arc::new(MockUListener::new()); + + // Register listener + transport.register_listener(&uri, None, listener.clone()).await.unwrap(); + + // Unregister listener should succeed + let result = transport.unregister_listener(&uri, None, listener.clone()).await; + assert!(result.is_ok(), "Listener unregistration should succeed"); + } + + #[tokio::test] + async fn test_unregister_nonexistent_listener() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener = Arc::new(MockUListener::new()); + + // Unregister non-existent listener should be no-op and succeed + let result = transport.unregister_listener(&uri, None, listener.clone()).await; + assert!(result.is_ok(), "Unregistering non-existent listener should succeed as no-op"); + } + + #[tokio::test] + async fn test_multiple_unregisters() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener = Arc::new(MockUListener::new()); + + // Register listener + transport.register_listener(&uri, None, listener.clone()).await.unwrap(); + + // First unregister should succeed + let result1 = transport.unregister_listener(&uri, None, listener.clone()).await; + assert!(result1.is_ok(), "First unregister should succeed"); + + // Second unregister should be no-op and succeed + let result2 = transport.unregister_listener(&uri, None, listener.clone()).await; + assert!(result2.is_ok(), "Second unregister should succeed as no-op"); + } + + #[tokio::test] + async fn test_unregister_cycle() { + use std::sync::atomic::{AtomicUsize, Ordering}; + use std::time::Duration; + + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts(&format!("vehicle{}", std::process::id()), 0x123, 1, 0x9000).unwrap(); + + struct CountingListener { + count: AtomicUsize, + } + + #[async_trait::async_trait] + impl UListener for CountingListener { + async fn on_receive(&self, _msg: UMessage) { + self.count.fetch_add(1, Ordering::SeqCst); + } + } + + let listener = Arc::new(CountingListener { + count: AtomicUsize::new(0), + }); + + // Register listener + transport.register_listener(&uri, None, listener.clone()).await.unwrap(); + + // Wait for registration to take effect + tokio::time::sleep(Duration::from_millis(100)).await; + + // Send a message + let message = UMessageBuilder::publish(uri.clone()).build().unwrap(); + transport.send(message.clone()).await.unwrap(); + + // Wait for message processing + tokio::time::sleep(Duration::from_millis(100)).await; + + // Record count before unregister + let count_before_unregister = listener.count.load(Ordering::SeqCst); + assert!(count_before_unregister >= 1, "Should have received at least one message"); + + // Unregister listener + transport.unregister_listener(&uri, None, listener.clone()).await.unwrap(); + + // Wait for unregister to take effect + tokio::time::sleep(Duration::from_millis(200)).await; + + // Send more messages after unregister + for _ in 0..3 { + transport.send(message.clone()).await.unwrap(); + tokio::time::sleep(Duration::from_millis(50)).await; + } + + // Wait to ensure no additional messages are processed + tokio::time::sleep(Duration::from_millis(200)).await; + + // Verify no additional messages were received after unregister + let count_after_unregister = listener.count.load(Ordering::SeqCst); + assert_eq!( + count_before_unregister, count_after_unregister, + "Should not receive messages after unregister. Before: {}, After: {}", + count_before_unregister, count_after_unregister + ); + } } diff --git a/src/receiver.rs b/src/receiver.rs index ecb3e13..984109c 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -135,12 +135,7 @@ async fn test_unregister_listener_stops_processing_of_messages() { let transport = Iceoryx2Transport::new().unwrap(); - let first_received = Arc::new(Notify::new()); - let second_received = Arc::new(Notify::new()); - struct TestListener { - first_barrier: Arc, - second_barrier: Arc, hit_count: AtomicUsize, } @@ -149,65 +144,60 @@ async fn test_unregister_listener_stops_processing_of_messages() { async fn on_receive(&self, _msg: UMessage) { let count = self.hit_count.fetch_add(1, Ordering::SeqCst); println!("Received a message, count = {}", count); - if count == 0 { - self.first_barrier.notify_one(); - } else { - self.second_barrier.notify_one(); - } } } let listener = Arc::new(TestListener { - first_barrier: first_received.clone(), - second_barrier: second_received.clone(), hit_count: AtomicUsize::new(0), }); - let uri = UUri::from_str("//vehicle/123/1/9000").unwrap(); + let uri = UUri::from_str(&format!("//vehicle{}/123/1/9000", std::process::id())).unwrap(); let msg = UMessageBuilder::publish(uri.clone()) .build() .expect("failed to build"); - let mut listener_registered=false; - // Register listener - if transport - .register_listener(&uri, None, listener.clone()).await.is_ok(){ - listener_registered = true; - } - //test if listener was registered - assert!(listener_registered, "Listener was not registered"); + // Register listener + transport.register_listener(&uri, None, listener.clone()).await.unwrap(); // Let subscriber start - tokio::time::sleep(Duration::from_millis(200)).await; + tokio::time::sleep(Duration::from_millis(100)).await; // Send first message transport.send(msg.clone()).await.unwrap(); - // Wait for first message to be received + // Wait for message processing + tokio::time::sleep(Duration::from_millis(100)).await; + + // Verify we received the first message assert!( - tokio::time::timeout(Duration::from_secs(3), first_received.notified()).await.is_ok(), - "Listener did not receive the first message" + listener.hit_count.load(Ordering::SeqCst) >= 1, + "Listener should have received at least one message" ); + // Record count before unregister + let count_before_unregister = listener.hit_count.load(Ordering::SeqCst); + // Unregister transport.unregister_listener(&uri, None, listener.clone()).await.unwrap(); - // Small delay to make sure unsubscribe has taken effect - tokio::time::sleep(Duration::from_millis(300)).await; + // Wait for unregister to take effect + tokio::time::sleep(Duration::from_millis(200)).await; - // Send again - transport.send(msg).await.unwrap(); + // Send more messages after unregister + for _ in 0..3 { + transport.send(msg.clone()).await.unwrap(); + tokio::time::sleep(Duration::from_millis(50)).await; + } - // Confirm second message is NOT received - assert!( - tokio::time::timeout(Duration::from_secs(3), second_received.notified()).await.is_err(), - "Expected no second message after unregister" - ); - // Final assertion to ensure exactly one message was received + // Wait a bit more to ensure no messages are processed + tokio::time::sleep(Duration::from_millis(200)).await; + + // Verify no additional messages were received after unregister + let count_after_unregister = listener.hit_count.load(Ordering::SeqCst); assert_eq!( - listener.hit_count.load(Ordering::SeqCst), - 1, - "Listener should only process one message" + count_before_unregister, count_after_unregister, + "Listener should not receive messages after unregister. Before: {}, After: {}", + count_before_unregister, count_after_unregister ); } From d815582428e9c70cd012a393460c41fd6825a3b5 Mon Sep 17 00:00:00 2001 From: arakabCL Date: Fri, 25 Jul 2025 14:02:24 +0100 Subject: [PATCH 36/42] Implement register_listener and unregister_listener functionality - Added working register_listener and unregister_listener methods - Removed wildcard support for exact URI matching - Added background task for message processing --- src/bin/listener.rs | 13 ++--- src/bin/sender.rs | 4 +- src/custom_header.rs | 10 ++-- src/lib.rs | 123 ++++++++++++++++++++++++++++++------------- src/raw_bytes.rs | 7 +-- src/receiver.rs | 59 ++++++++++++--------- 6 files changed, 136 insertions(+), 80 deletions(-) diff --git a/src/bin/listener.rs b/src/bin/listener.rs index 82cf8b5..1cef601 100644 --- a/src/bin/listener.rs +++ b/src/bin/listener.rs @@ -1,10 +1,10 @@ -use std::sync::Arc; -use tokio::sync::Notify; use async_trait::async_trait; -use up_rust::{UListener, UMessage, UUri, UTransport}; use env_logger; -use std::sync::Once; use std::str::FromStr; +use std::sync::Arc; +use std::sync::Once; +use tokio::sync::Notify; +use up_rust::{UListener, UMessage, UTransport, UUri}; use up_transport_iceoryx2_rust::Iceoryx2Transport; static INIT_LOGGER: Once = Once::new(); @@ -35,13 +35,14 @@ impl UListener for Receiver { } } - #[tokio::main] async fn main() -> Result<(), Box> { init_logger(); let notify = Arc::new(Notify::new()); - let receiver = Arc::new(Receiver { notify: notify.clone() }); + let receiver = Arc::new(Receiver { + notify: notify.clone(), + }); let topic = UUri::from_str("//vehicle_shared/10A10B/1/CA5D")?; let transport = Iceoryx2Transport::new().unwrap(); diff --git a/src/bin/sender.rs b/src/bin/sender.rs index 77663ca..8bdbe3a 100644 --- a/src/bin/sender.rs +++ b/src/bin/sender.rs @@ -1,8 +1,8 @@ use env_logger; -use std::sync::Once; use std::str::FromStr; +use std::sync::Once; -use up_rust::{UMessageBuilder, UPayloadFormat, UUri, UTransport}; +use up_rust::{UMessageBuilder, UPayloadFormat, UTransport, UUri}; use up_transport_iceoryx2_rust::Iceoryx2Transport; static INIT_LOGGER: Once = Once::new(); diff --git a/src/custom_header.rs b/src/custom_header.rs index efdd826..516b0f0 100644 --- a/src/custom_header.rs +++ b/src/custom_header.rs @@ -24,12 +24,12 @@ impl CustomHeader { } else { 1 // Default version }; - + let timestamp = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_millis() as u64; - + Ok(Self { version, timestamp }) } } @@ -42,14 +42,14 @@ impl From<&CustomHeader> for UAttributes { // Map CustomHeader fields back to UAttributes using available fields // Based on the error message, available fields are: id, type_, source, sink, priority, etc. - + // Set default values for required fields attrs.type_ = up_rust::UMessageType::UMESSAGE_TYPE_PUBLISH.into(); attrs.priority = up_rust::UPriority::UPRIORITY_CS4.into(); - + // Note: version and timestamp information is preserved in the CustomHeader // but UAttributes doesn't have direct fields for them, so we use defaults - + attrs } } diff --git a/src/lib.rs b/src/lib.rs index b9a4aa5..620559c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -222,9 +222,11 @@ impl Iceoryx2Transport { .filter(|(service_name, listeners_vec)| { !listeners_vec.is_empty() && subscribers.contains_key(*service_name) }) - .map(|(service_name, listeners_vec)| (service_name.clone(), listeners_vec.clone())) + .map(|(service_name, listeners_vec)| { + (service_name.clone(), listeners_vec.clone()) + }) .collect(); - + for (service_name, listeners_to_notify) in active_services { if let Some(subscriber) = subscribers.get(&service_name) { while let Some(sample) = subscriber.receive().ok().flatten() { @@ -234,10 +236,11 @@ impl Iceoryx2Transport { // Reconstruct UMessage with deserialized header to UAttributes let mut new_umessage = UMessage::new(); - + // Extract attributes (UAttributes::from(custom_header) - full impl: parse version, deserialize Protobuf) - new_umessage.attributes = MessageField::some(UAttributes::from(sample.user_header())); - + new_umessage.attributes = + MessageField::some(UAttributes::from(sample.user_header())); + // Attach payload bytes new_umessage.payload = Some(payload_bytes.into()); @@ -276,7 +279,7 @@ impl Iceoryx2Transport { // Remove from hashmap: listeners.get_mut(&service_name).and_then(|vec| vec.remove(&listener)); if let Some(listener_vec) = listeners.get_mut(&service_name) { listener_vec.retain(|l| !Arc::ptr_eq(l, listener)); - + // If last listener, cleanup subscriber (unsubscribe) if listener_vec.is_empty() { listeners.remove(&service_name); @@ -311,35 +314,40 @@ impl Iceoryx2Transport { let service_name_res: Result = service_name.as_str().try_into(); let service = node .service_builder(&service_name_res.map_err(|e| { - UStatus::fail_with_code(UCode::INVALID_ARGUMENT, &format!("Invalid service name: {}", e)) + UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + &format!("Invalid service name: {}", e), + ) })?) .publish_subscribe::() .user_header::() .open_or_create() .map_err(|e| { - UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to create service: {}", e)) + UStatus::fail_with_code( + UCode::INTERNAL, + &format!("Failed to create service: {}", e), + ) })?; - let subscriber = service - .subscriber_builder() - .create() - .map_err(|e| { - UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to create subscriber: {}", e)) - })?; + let subscriber = service.subscriber_builder().create().map_err(|e| { + UStatus::fail_with_code( + UCode::INTERNAL, + &format!("Failed to create subscriber: {}", e), + ) + })?; subscribers.insert(service_name.clone(), subscriber); } // Add listener to hashmap: listeners.entry(service_name).or_insert(Vec::new()).push(listener); - listeners.entry(service_name).or_insert_with(Vec::new).push(listener); + listeners + .entry(service_name) + .or_insert_with(Vec::new) + .push(listener); Ok(()) } fn handle_send( - publisher: &iceoryx2::port::publisher::Publisher< - ipc::Service, - RawBytes, - CustomHeader, - >, + publisher: &iceoryx2::port::publisher::Publisher, message: UMessage, ) -> Result<(), UStatus> { let payload_bytes = message.payload.clone().unwrap_or_default().to_vec(); @@ -436,7 +444,7 @@ mod tests { use super::*; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; - use up_rust::{UMessageBuilder, UPayloadFormat, MockUListener}; + use up_rust::{MockUListener, UMessageBuilder, UPayloadFormat}; fn dummy_uuid() -> up_rust::UUID { up_rust::UUID::build() @@ -512,7 +520,9 @@ mod tests { let listener = Arc::new(MockUListener::new()); // Register listener should succeed - let result = transport.register_listener(&uri, None, listener.clone()).await; + let result = transport + .register_listener(&uri, None, listener.clone()) + .await; assert!(result.is_ok(), "Listener registration should succeed"); } @@ -524,12 +534,22 @@ mod tests { let listener2 = Arc::new(MockUListener::new()); // Register first listener - let result1 = transport.register_listener(&uri, None, listener1.clone()).await; - assert!(result1.is_ok(), "First listener registration should succeed"); + let result1 = transport + .register_listener(&uri, None, listener1.clone()) + .await; + assert!( + result1.is_ok(), + "First listener registration should succeed" + ); // Register second listener for same URI (should reuse subscriber) - let result2 = transport.register_listener(&uri, None, listener2.clone()).await; - assert!(result2.is_ok(), "Second listener registration should succeed"); + let result2 = transport + .register_listener(&uri, None, listener2.clone()) + .await; + assert!( + result2.is_ok(), + "Second listener registration should succeed" + ); } #[tokio::test] @@ -539,10 +559,15 @@ mod tests { let listener = Arc::new(MockUListener::new()); // Register listener - transport.register_listener(&uri, None, listener.clone()).await.unwrap(); + transport + .register_listener(&uri, None, listener.clone()) + .await + .unwrap(); // Unregister listener should succeed - let result = transport.unregister_listener(&uri, None, listener.clone()).await; + let result = transport + .unregister_listener(&uri, None, listener.clone()) + .await; assert!(result.is_ok(), "Listener unregistration should succeed"); } @@ -553,8 +578,13 @@ mod tests { let listener = Arc::new(MockUListener::new()); // Unregister non-existent listener should be no-op and succeed - let result = transport.unregister_listener(&uri, None, listener.clone()).await; - assert!(result.is_ok(), "Unregistering non-existent listener should succeed as no-op"); + let result = transport + .unregister_listener(&uri, None, listener.clone()) + .await; + assert!( + result.is_ok(), + "Unregistering non-existent listener should succeed as no-op" + ); } #[tokio::test] @@ -564,14 +594,21 @@ mod tests { let listener = Arc::new(MockUListener::new()); // Register listener - transport.register_listener(&uri, None, listener.clone()).await.unwrap(); + transport + .register_listener(&uri, None, listener.clone()) + .await + .unwrap(); // First unregister should succeed - let result1 = transport.unregister_listener(&uri, None, listener.clone()).await; + let result1 = transport + .unregister_listener(&uri, None, listener.clone()) + .await; assert!(result1.is_ok(), "First unregister should succeed"); // Second unregister should be no-op and succeed - let result2 = transport.unregister_listener(&uri, None, listener.clone()).await; + let result2 = transport + .unregister_listener(&uri, None, listener.clone()) + .await; assert!(result2.is_ok(), "Second unregister should succeed as no-op"); } @@ -581,8 +618,9 @@ mod tests { use std::time::Duration; let transport = Iceoryx2Transport::new().unwrap(); - let uri = UUri::try_from_parts(&format!("vehicle{}", std::process::id()), 0x123, 1, 0x9000).unwrap(); - + let uri = UUri::try_from_parts(&format!("vehicle{}", std::process::id()), 0x123, 1, 0x9000) + .unwrap(); + struct CountingListener { count: AtomicUsize, } @@ -599,7 +637,10 @@ mod tests { }); // Register listener - transport.register_listener(&uri, None, listener.clone()).await.unwrap(); + transport + .register_listener(&uri, None, listener.clone()) + .await + .unwrap(); // Wait for registration to take effect tokio::time::sleep(Duration::from_millis(100)).await; @@ -613,10 +654,16 @@ mod tests { // Record count before unregister let count_before_unregister = listener.count.load(Ordering::SeqCst); - assert!(count_before_unregister >= 1, "Should have received at least one message"); + assert!( + count_before_unregister >= 1, + "Should have received at least one message" + ); // Unregister listener - transport.unregister_listener(&uri, None, listener.clone()).await.unwrap(); + transport + .unregister_listener(&uri, None, listener.clone()) + .await + .unwrap(); // Wait for unregister to take effect tokio::time::sleep(Duration::from_millis(200)).await; diff --git a/src/raw_bytes.rs b/src/raw_bytes.rs index 537f9cc..7960495 100644 --- a/src/raw_bytes.rs +++ b/src/raw_bytes.rs @@ -1,8 +1,5 @@ use iceoryx2::prelude::*; -use iceoryx2_bb_container::{ - vec::FixedSizeVec, - byte_string::FixedSizeByteString, -}; +use iceoryx2_bb_container::{byte_string::FixedSizeByteString, vec::FixedSizeVec}; /// A minimal wrapper to hold raw byte payloads for Iceoryx2. /// /// Iceoryx2 requires payload types to implement ZeroCopySend. @@ -30,4 +27,4 @@ impl RawBytes { } RawBytes { data } } -} \ No newline at end of file +} diff --git a/src/receiver.rs b/src/receiver.rs index 984109c..ef0b95b 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -3,16 +3,16 @@ use std::sync::Arc; use std::time::Duration; use async_trait::async_trait; -use tokio::sync::Notify; use log::info; +use tokio::sync::Notify; +use env_logger; +use iceoryx2::prelude::*; +use std::str::FromStr; use up_rust::{ - MockUListener,UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, + MockUListener, UAttributes, UCode, UListener, UMessage, UMessageBuilder, UPayloadFormat, UStatus, UTransport, UUri, }; -use std::str::FromStr; -use iceoryx2::prelude::*; -use env_logger; use std::sync::Once; @@ -78,14 +78,13 @@ async fn register_listener_and_send( umessage.type_unchecked().to_cloudevent_type() ); transport.send(umessage).await?; - Ok(tokio::time::timeout(Duration::from_secs(3), notify.notified()) - .await - .map_err(|_| { - UStatus::fail_with_code( - UCode::DEADLINE_EXCEEDED, - "did not receive message in time", - ) - })?) + Ok( + tokio::time::timeout(Duration::from_secs(3), notify.notified()) + .await + .map_err(|_| { + UStatus::fail_with_code(UCode::DEADLINE_EXCEEDED, "did not receive message in time") + })?, + ) } #[test_case::test_case("vehicle1", 12_000, "//vehicle1/10A10B/1/CA5D", "//vehicle1/10A10B/1/CA5D"; "specific source filter")] @@ -114,13 +113,21 @@ async fn test_publish_gets_to_listener( async fn test_exact_listener_dispatch() -> Result<(), Box> { let transport = Iceoryx2Transport::new().unwrap(); let listener_uri = UUri::from_str("//vehicle1/10A10B/1/CA5D")?; - let matching_message = UMessageBuilder::publish(listener_uri.clone()).build_with_payload(vec![1, 2, 3], UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; - let non_matching_message = UMessageBuilder::publish(UUri::from_str("//vehicle2/10A10B/1/CA5D")?).build_with_payload(vec![4, 5, 6], UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; + let matching_message = UMessageBuilder::publish(listener_uri.clone()) + .build_with_payload(vec![1, 2, 3], UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; + let non_matching_message = + UMessageBuilder::publish(UUri::from_str("//vehicle2/10A10B/1/CA5D")?) + .build_with_payload(vec![4, 5, 6], UPayloadFormat::UPAYLOAD_FORMAT_RAW)?; let received_notify = Arc::new(Notify::new()); - let listener = Arc::new(Receiver::new(matching_message.clone(), received_notify.clone())); + let listener = Arc::new(Receiver::new( + matching_message.clone(), + received_notify.clone(), + )); - transport.register_listener(&listener_uri, None, listener).await?; + transport + .register_listener(&listener_uri, None, listener) + .await?; transport.send(non_matching_message).await?; transport.send(matching_message).await?; @@ -157,7 +164,10 @@ async fn test_unregister_listener_stops_processing_of_messages() { .expect("failed to build"); // Register listener - transport.register_listener(&uri, None, listener.clone()).await.unwrap(); + transport + .register_listener(&uri, None, listener.clone()) + .await + .unwrap(); // Let subscriber start tokio::time::sleep(Duration::from_millis(100)).await; @@ -178,7 +188,10 @@ async fn test_unregister_listener_stops_processing_of_messages() { let count_before_unregister = listener.hit_count.load(Ordering::SeqCst); // Unregister - transport.unregister_listener(&uri, None, listener.clone()).await.unwrap(); + transport + .unregister_listener(&uri, None, listener.clone()) + .await + .unwrap(); // Wait for unregister to take effect tokio::time::sleep(Duration::from_millis(200)).await; @@ -206,11 +219,9 @@ async fn test_mock_listener() { use up_rust::MockUListener; let mut listener = MockUListener::new(); - listener - .expect_on_receive() - .returning(|_message| { - println!("Mock listener called!"); - }); + listener.expect_on_receive().returning(|_message| { + println!("Mock listener called!"); + }); let message = UMessage::new(); From 8e9b311c5ce15abd9a5a0dba153324ce0eda472c Mon Sep 17 00:00:00 2001 From: kwarraich Date: Mon, 28 Jul 2025 16:16:17 -0500 Subject: [PATCH 37/42] fixing workflow error --- src/receiver.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/receiver.rs b/src/receiver.rs index ef0b95b..b5892a1 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -163,7 +163,7 @@ async fn test_unregister_listener_stops_processing_of_messages() { .build() .expect("failed to build"); - // Register listener + // Registers listener transport .register_listener(&uri, None, listener.clone()) .await From d33aab80c0f62f93af8bc291ce9239531a5119f3 Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Wed, 30 Jul 2025 03:26:58 +0530 Subject: [PATCH 38/42] Update lib.rs Trying to resolve the build error --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 1e5b43e..cfbd1f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -773,5 +773,4 @@ fn test_fail_missing_source_error() { assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT)); } - } } From 84c6d60419d564a35cb41f97f3295d43772609d9 Mon Sep 17 00:00:00 2001 From: kwarraich <111186505+kwarraich@users.noreply.github.com> Date: Tue, 29 Jul 2025 22:01:48 -0500 Subject: [PATCH 39/42] Update lib.rs --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index cfbd1f1..e34e876 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -773,4 +773,4 @@ fn test_fail_missing_source_error() { assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT)); } -} + From 265fba14762ffc5264dd043cb6ea42c20fe60b6e Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Thu, 31 Jul 2025 00:51:01 +0530 Subject: [PATCH 40/42] Update src/lib.rs Co-authored-by: Kai Hudalla --- src/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e34e876..c4e2964 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -303,11 +303,7 @@ impl Iceoryx2Transport { sink_filter: Option<&UUri>, listener: Arc, ) -> Result<(), UStatus> { - let service_name = match Self::compute_listener_service_name(&source_filter, sink_filter) { - Ok(name) => name, - Err(e) => { - return Err(e); - } + let service_name = Self::compute_listener_service_name(&source_filter, sink_filter)?; }; // Create subscriber if it doesn't exist for this service_name From d453dec1e4316388cd5e905ffce5dedafe42c69a Mon Sep 17 00:00:00 2001 From: vidishac2004 <144144085+vidishac2004@users.noreply.github.com> Date: Sat, 2 Aug 2025 11:30:51 +0530 Subject: [PATCH 41/42] Remove .DS_Store and add it to .gitignore --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 1 + 2 files changed, 1 insertion(+) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Wed, 6 Aug 2025 21:35:56 -0500 Subject: [PATCH 42/42] removed rawbytes --- src/lib.rs | 688 +++++++++++++++++++++++++---------------------------- 1 file changed, 318 insertions(+), 370 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c4e2964..f976718 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,13 +4,13 @@ use protobuf::MessageField; use std::sync::Arc; use up_rust::{UAttributes, UCode, UListener, UMessage, UStatus, UTransport, UUri}; - mod custom_header; pub use custom_header::CustomHeader; mod raw_bytes; use raw_bytes::RawBytes; +use iceoryx2_bb_container::vec::FixedSizeVec; use std::collections::HashMap; use std::thread; @@ -36,6 +36,11 @@ enum TransportCommand { pub struct Iceoryx2Transport { command_sender: std::sync::mpsc::Sender, } +enum MessageType { + RpcRequest, + RpcResponseOrNotification, + Publish, +} impl Iceoryx2Transport { pub fn new() -> Result { @@ -47,22 +52,21 @@ impl Iceoryx2Transport { Ok(Self { command_sender: tx }) } - fn encode_uuri_segments(uuri: &UUri) -> Vec { vec![ uuri.authority_name.clone(), - Self::encode_hex_no_leading_zeros(uuri.uentity_type_id() as u32), - Self::encode_hex_no_leading_zeros(uuri.uentity_instance_id() as u32), - Self::encode_hex_no_leading_zeros(uuri.uentity_major_version() as u32), - Self::encode_hex_no_leading_zeros(uuri.resource_id() as u32), + Self::encode_hex(uuri.uentity_type_id() as u32), + Self::encode_hex(uuri.uentity_instance_id() as u32), + Self::encode_hex(uuri.uentity_major_version() as u32), + Self::encode_hex(uuri.resource_id() as u32), ] } - fn encode_hex_no_leading_zeros(value: u32) -> String { + fn encode_hex(value: u32) -> String { format!("{:X}", value) } - fn compute_service_name(message: &UMessage) -> Result { + fn compute_service_name_from_message(message: &UMessage) -> Result { let join_segments = |segments: Vec| segments.join("/"); if message.is_publish() { @@ -100,6 +104,67 @@ impl Iceoryx2Transport { } } + fn compute_service_name_from_uris( + source: &UUri, + sink: Option<&UUri>, + ) -> Result { + let join_segments = |segments: Vec| segments.join("/"); + + match Self::determine_message_type(source, sink)? { + MessageType::RpcRequest => { + let Some(sink_uri) = sink else { + return Err(UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + "sink required for RpcRequest", + )); + }; + let segments = Self::encode_uuri_segments(sink_uri); + Ok(format!("up/{}", join_segments(segments))) + } + MessageType::RpcResponseOrNotification => { + let Some(sink_uri) = sink else { + return Err(UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + "sink required for ResponseOrNotification", + )); + }; + let source_segments = Self::encode_uuri_segments(source); + let sink_segments = Self::encode_uuri_segments(sink_uri); + Ok(format!( + "up/{}/{}", + join_segments(source_segments), + join_segments(sink_segments) + )) + } + MessageType::Publish => { + let segments = Self::encode_uuri_segments(source); + Ok(format!("up/{}", join_segments(segments))) + } + } + } + + fn determine_message_type(source: &UUri, sink: Option<&UUri>) -> Result { + let src_id = source.resource_id; + let sink_id = sink.map(|s| s.resource_id); + + if src_id == 0 { + if let Some(id) = sink_id { + if id >= 1 && id <= 0x7FFF { + return Ok(MessageType::RpcRequest); + } + } + } else if sink_id == Some(0) && src_id >= 1 && src_id <= 0xFFFE { + return Ok(MessageType::RpcResponseOrNotification); + } else if src_id >= 1 && src_id <= 0x7FFF { + return Ok(MessageType::Publish); + } + + Err(UStatus::fail_with_code( + UCode::INVALID_ARGUMENT, + "Unsupported UMessageType", + )) + } + fn compute_listener_service_name( source_filter: &UUri, sink_filter: Option<&UUri>, @@ -122,7 +187,6 @@ impl Iceoryx2Transport { } } } - fn background_task(rx: std::sync::mpsc::Receiver) { let rt = tokio::runtime::Builder::new_current_thread() .enable_all() @@ -140,12 +204,20 @@ impl Iceoryx2Transport { let mut publishers: HashMap< String, - iceoryx2::port::publisher::Publisher, + iceoryx2::port::publisher::Publisher< + ipc::Service, + FixedSizeVec, + CustomHeader, + >, > = HashMap::new(); let mut subscribers: HashMap< String, - iceoryx2::port::subscriber::Subscriber, + iceoryx2::port::subscriber::Subscriber< + ipc::Service, + FixedSizeVec, + CustomHeader, + >, > = HashMap::new(); let mut listeners: HashMap>> = HashMap::new(); @@ -154,13 +226,14 @@ impl Iceoryx2Transport { while let Ok(command) = rx.try_recv() { match command { TransportCommand::Send { message, response } => { - let service_name = match Self::compute_service_name(&message) { - Ok(name) => name, - Err(e) => { - let _ = response.send(Err(e)); - continue; - } - }; + let service_name = + match Self::compute_service_name_from_message(&message) { + Ok(name) => name, + Err(e) => { + let _ = response.send(Err(e)); + continue; + } + }; let publisher = publishers.entry(service_name.clone()).or_insert_with(|| { @@ -168,7 +241,7 @@ impl Iceoryx2Transport { service_name.as_str().try_into(); let service = node .service_builder(&service_name_res.unwrap()) - .publish_subscribe::() + .publish_subscribe::>() .user_header::() .open_or_create() .expect("Failed to create service"); @@ -216,8 +289,6 @@ impl Iceoryx2Transport { } } - // Integrate dispatch: In polling/receive, extract attributes and reconstruct UMessage - // Only process subscribers that have active listeners let active_services: Vec<(String, Vec>)> = listeners .iter() .filter(|(service_name, listeners_vec)| { @@ -232,20 +303,12 @@ impl Iceoryx2Transport { if let Some(subscriber) = subscribers.get(&service_name) { while let Some(sample) = subscriber.receive().ok().flatten() { for listener in &listeners_to_notify { - // Extract payload bytes - let payload_bytes = sample.payload().to_bytes(); - - // Reconstruct UMessage with deserialized header to UAttributes + let payload_bytes = sample.payload().as_slice(); let mut new_umessage = UMessage::new(); - - // Extract attributes (UAttributes::from(custom_header) - full impl: parse version, deserialize Protobuf) new_umessage.attributes = MessageField::some(UAttributes::from(sample.user_header())); + new_umessage.payload = Some(payload_bytes.to_vec().into()); - // Attach payload bytes - new_umessage.payload = Some(payload_bytes.into()); - - // Invoke listener.on_message with reconstructed UMessage let listener_clone = listener.clone(); tokio::spawn(async move { listener_clone.on_receive(new_umessage).await; @@ -260,35 +323,30 @@ impl Iceoryx2Transport { }); } - fn handle_unregister_listener( - subscribers: &mut HashMap< - String, - iceoryx2::port::subscriber::Subscriber, + fn handle_send( + publisher: &iceoryx2::port::publisher::Publisher< + ipc::Service, + FixedSizeVec, + CustomHeader, >, - listeners: &mut HashMap>>, - source_filter: UUri, - sink_filter: Option<&UUri>, - listener: &Arc, + message: UMessage, ) -> Result<(), UStatus> { - let service_name = match Self::compute_listener_service_name(&source_filter, sink_filter) { - Ok(name) => name, - Err(e) => { - return Err(e); - } - }; + let payload_bytes = message.payload.clone().unwrap_or_default().to_vec(); + let mut payload_vec = FixedSizeVec::::new(); + assert!(payload_vec.extend_from_slice(&payload_bytes)); + let header = CustomHeader::from_message(&message)?; - // Remove from hashmap: listeners.get_mut(&service_name).and_then(|vec| vec.remove(&listener)); - if let Some(listener_vec) = listeners.get_mut(&service_name) { - listener_vec.retain(|l| !Arc::ptr_eq(l, listener)); + let sample = publisher.loan_uninit().map_err(|e| { + UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")) + })?; - // If last listener, cleanup subscriber (unsubscribe) - if listener_vec.is_empty() { - listeners.remove(&service_name); - subscribers.remove(&service_name); - } - } + let mut sample_final = sample.write_payload(payload_vec); + *sample_final.user_header_mut() = header; + + sample_final.send().map_err(|e| { + UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to send: {e}")) + })?; - // Return success if removed (or no-op if listener wasn't found) Ok(()) } @@ -296,7 +354,11 @@ impl Iceoryx2Transport { node: &Node, subscribers: &mut HashMap< String, - iceoryx2::port::subscriber::Subscriber, + iceoryx2::port::subscriber::Subscriber< + ipc::Service, + FixedSizeVec, + CustomHeader, + >, >, listeners: &mut HashMap>>, source_filter: UUri, @@ -304,9 +366,7 @@ impl Iceoryx2Transport { listener: Arc, ) -> Result<(), UStatus> { let service_name = Self::compute_listener_service_name(&source_filter, sink_filter)?; - }; - // Create subscriber if it doesn't exist for this service_name if !subscribers.contains_key(&service_name) { let service_name_res: Result = service_name.as_str().try_into(); let service = node @@ -316,7 +376,7 @@ impl Iceoryx2Transport { &format!("Invalid service name: {}", e), ) })?) - .publish_subscribe::() + .publish_subscribe::>() .user_header::() .open_or_create() .map_err(|e| { @@ -335,7 +395,6 @@ impl Iceoryx2Transport { subscribers.insert(service_name.clone(), subscriber); } - // Add listener to hashmap: listeners.entry(service_name).or_insert(Vec::new()).push(listener); listeners .entry(service_name) .or_insert_with(Vec::new) @@ -343,34 +402,38 @@ impl Iceoryx2Transport { Ok(()) } - fn handle_send( - publisher: &iceoryx2::port::publisher::Publisher, - message: UMessage, + fn handle_unregister_listener( + subscribers: &mut HashMap< + String, + iceoryx2::port::subscriber::Subscriber< + ipc::Service, + FixedSizeVec, + CustomHeader, + >, + >, + listeners: &mut HashMap>>, + source_filter: UUri, + sink_filter: Option<&UUri>, + listener: &Arc, ) -> Result<(), UStatus> { - let payload_bytes = message.payload.clone().unwrap_or_default().to_vec(); - let raw_payload = RawBytes::from_bytes(&payload_bytes); - let header = CustomHeader::from_message(&message)?; - - let sample = publisher.loan_uninit().map_err(|e| { - UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to loan sample: {e}")) - })?; + let service_name = match Self::compute_listener_service_name(&source_filter, sink_filter) { + Ok(name) => name, + Err(e) => return Err(e), + }; - let mut sample_final = sample.write_payload(raw_payload); - *sample_final.user_header_mut() = header; + if let Some(listener_vec) = listeners.get_mut(&service_name) { + listener_vec.retain(|l| !Arc::ptr_eq(l, listener)); - sample_final.send().map_err(|e| { - UStatus::fail_with_code(UCode::INTERNAL, &format!("Failed to send: {e}")) - })?; + if listener_vec.is_empty() { + listeners.remove(&service_name); + subscribers.remove(&service_name); + } + } Ok(()) } } -pub enum MessageType { - RpcRequest, - RpcResponseOrNotification, - Publish, -} #[async_trait] impl UTransport for Iceoryx2Transport { async fn send(&self, message: UMessage) -> Result<(), UStatus> { @@ -439,334 +502,219 @@ impl UTransport for Iceoryx2Transport { } } -mod receiver; - -#[allow(dead_code)] -impl Iceoryx2Transport { - fn encode_uuri_segments(uuri: &UUri) -> Vec { - vec![ - uuri.authority_name.clone(), - Self::encode_hex(uuri.uentity_type_id() as u32), - Self::encode_hex(uuri.uentity_instance_id() as u32), - Self::encode_hex(uuri.uentity_major_version() as u32), - Self::encode_hex(uuri.resource_id() as u32), - ] - } - - fn encode_hex(value: u32) -> String { - format!("{:X}", value) - } - - fn determine_message_type(source: &UUri, sink: Option<&UUri>) -> Result { - let src_id = source.resource_id; - let sink_id = sink.map(|s| s.resource_id); - - if src_id == 0 { - if let Some(id) = sink_id { - if id >= 1 && id <= 0x7FFF { - return Ok(MessageType::RpcRequest); - } - } - } else if sink_id == Some(0) && src_id >= 1 && src_id <= 0xFFFE { - return Ok(MessageType::RpcResponseOrNotification); - } else if src_id >= 1 && src_id <= 0x7FFF { - return Ok(MessageType::Publish); - } - - Err(UStatus::fail_with_code( - UCode::INVALID_ARGUMENT, - "Unsupported UMessageType", - )) - } - - fn compute_service_name(source: &UUri, sink: Option<&UUri>) -> Result { - let join_segments = |segments: Vec| segments.join("/"); - - match Self::determine_message_type(source, sink)? { - MessageType::RpcRequest => { - let Some(sink_uri) = sink else { - return Err(UStatus::fail_with_code( - UCode::INVALID_ARGUMENT, - "sink required for RpcRequest", - )); - }; - let segments = Self::encode_uuri_segments(sink_uri); - Ok(format!("up/{}", join_segments(segments))) - } - MessageType::RpcResponseOrNotification => { - let Some(sink_uri) = sink else { - return Err(UStatus::fail_with_code( - UCode::INVALID_ARGUMENT, - "sink required for ResponseOrNotification", - )); - }; - let source_segments = Self::encode_uuri_segments(source); - let sink_segments = Self::encode_uuri_segments(sink_uri); - Ok(format!( - "up/{}/{}", - join_segments(source_segments), - join_segments(sink_segments) - )) - } - MessageType::Publish => { - let segments = Self::encode_uuri_segments(source); - Ok(format!("up/{}", join_segments(segments))) - } - } - } -} - - #[cfg(test)] mod tests { use super::*; - use std::sync::atomic::{AtomicBool, Ordering}; - use std::time::Duration; - use up_rust::{MockUListener, UMessageBuilder, UPayloadFormat}; - - fn dummy_uuid() -> up_rust::UUID { - up_rust::UUID::build() - } - + use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; + use std::time::Duration; + use up_rust::{MockUListener, UMessageBuilder, UPayloadFormat}; fn test_uri(authority: &str, instance: u16, typ: u16, version: u8, resource: u16) -> UUri { let entity_id = ((instance as u32) << 16) | (typ as u32); UUri::try_from_parts(authority, entity_id, version, resource).unwrap() } -// performing successful tests for service name computation - -#[test] -// [specitem,oft-sid="dsn~up-transport-iceoryx2-service-name~1",oft-needs="utest"] -fn test_publish_service_name() { - let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x7FFF); - - let name = Iceoryx2Transport::compute_service_name(&source, None).unwrap(); - assert_eq!(name, "up/device1/10AB/0/3/7FFF"); -} + fn dummy_uuid() -> up_rust::UUID { + up_rust::UUID::build() + } -#[test] -// [specitem,oft-sid="dsn~up-transport-iceoryx2-service-name~1",oft-needs="utest"] -fn test_notification_service_name() { - let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); - let sink = test_uri("device1", 0x0000, 0x30EF, 0x04, 0x0000); - let name = Iceoryx2Transport::compute_service_name(&source, Some(&sink)).unwrap(); - assert_eq!(name, "up/device1/10AB/0/3/80CD/device1/30EF/0/4/0"); -} + #[test] + fn test_publish_service_name() { + let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x7FFF); + let name = Iceoryx2Transport::compute_service_name_from_uris(&source, None).unwrap(); + assert_eq!(name, "up/device1/10AB/0/3/7FFF"); + } + #[test] + fn test_notification_service_name() { + let source = test_uri("device1", 0x0000, 0x10AB, 0x03, 0x80CD); + let sink = test_uri("device1", 0x0000, 0x30EF, 0x04, 0x0000); + let name = Iceoryx2Transport::compute_service_name_from_uris(&source, Some(&sink)).unwrap(); assert_eq!(name, "up/device1/10AB/0/3/80CD/device1/30EF/0/4/0"); } #[test] -// [specitem,oft-sid="dsn~up-transport-iceoryx2-service-name~1",oft-needs="utest"] -fn test_rpc_request_service_name() { - let sink = test_uri("device1", 0x0004, 0x03AB, 0x03, 0x0000); - let reply_to = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); - - let name = Iceoryx2Transport::compute_service_name(&sink, Some(&reply_to)).unwrap(); - assert_eq!(name, "up/device1/CD/0/4/B"); -} - - - #[test] -// [specitem,oft-sid="dsn~up-transport-iceoryx2-service-name~1",oft-needs="utest"] -fn test_rpc_response_service_name() { - let source = test_uri("device1", 0x0000, 0x00CD, 0x04, 0xB); - let sink = test_uri("device1", 0x0004, 0x3AB, 0x3, 0x0000); - - let name = Iceoryx2Transport::compute_service_name(&source, Some(&sink)).unwrap(); - assert_eq!(name, "up/device1/CD/0/4/B/device1/3AB/4/3/0"); -} - -#[test] -// .specitem[dsn~up-attributes-request-source~1] -// .specitem[dsn~up-attributes-response-source~1] -// .specitem[dsn~up-attributes-notification-source~1] -fn test_missing_uri_error() { - let uuri = UUri::new(); - let result = Iceoryx2Transport::compute_service_name(&uuri, None); - assert!(result.is_err()); - assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT); -} - -#[tokio::test] -async fn test_register_listener_creates_subscriber() { - let transport = Iceoryx2Transport::new().unwrap(); - let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); - let listener = Arc::new(MockUListener::new()); - - let result = transport - .register_listener(&uri, None, listener.clone()) - .await; - assert!(result.is_ok(), "Listener registration should succeed"); -} - -#[tokio::test] -async fn test_register_duplicate_listeners() { - let transport = Iceoryx2Transport::new().unwrap(); - let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); - let listener1 = Arc::new(MockUListener::new()); - let listener2 = Arc::new(MockUListener::new()); - - let result1 = transport - .register_listener(&uri, None, listener1.clone()) - .await; - assert!(result1.is_ok(), "First listener registration should succeed"); - - let result2 = transport - .register_listener(&uri, None, listener2.clone()) - .await; - assert!(result2.is_ok(), "Second listener registration should succeed"); -} + fn test_rpc_request_service_name() { + let sink = test_uri("device1", 0x0004, 0x03AB, 0x03, 0x0000); + let reply_to = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); + let name = + Iceoryx2Transport::compute_service_name_from_uris(&sink, Some(&reply_to)).unwrap(); + assert_eq!(name, "up/device1/CD/0/4/B"); + } -#[tokio::test] -async fn test_unregister_listener_cleanup() { - let transport = Iceoryx2Transport::new().unwrap(); - let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); - let listener = Arc::new(MockUListener::new()); - - transport - .register_listener(&uri, None, listener.clone()) - .await - .unwrap(); - - let result = transport - .unregister_listener(&uri, None, listener.clone()) - .await; - assert!(result.is_ok(), "Listener unregistration should succeed"); -} + #[test] + fn test_rpc_response_service_name() { + let source = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000B); + let sink = test_uri("device1", 0x0004, 0x03AB, 0x03, 0x0000); + let name = Iceoryx2Transport::compute_service_name_from_uris(&source, Some(&sink)).unwrap(); + assert_eq!(name, "up/device1/CD/0/4/B/device1/3AB/4/3/0"); + } -#[tokio::test] -async fn test_unregister_nonexistent_listener() { - let transport = Iceoryx2Transport::new().unwrap(); - let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); - let listener = Arc::new(MockUListener::new()); + #[test] + fn test_fail_resource_id_error() { + let source = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x0000); + let sink = test_uri("device1", 0x0004, 0x03AB, 0x03, 0x0000); + let result = Iceoryx2Transport::compute_service_name_from_uris(&source, Some(&sink)); + assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT)); + } - let result = transport - .unregister_listener(&uri, None, listener.clone()) - .await; - assert!(result.is_ok(), "Unregistering non-existent listener should succeed as no-op"); -} + #[test] + fn test_fail_missing_sink_error() { + let source = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x0000); + let result = Iceoryx2Transport::compute_service_name_from_uris(&source, None); + assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT)); + } -#[tokio::test] -async fn test_multiple_unregisters() { - let transport = Iceoryx2Transport::new().unwrap(); - let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); - let listener = Arc::new(MockUListener::new()); - - transport - .register_listener(&uri, None, listener.clone()) - .await - .unwrap(); - - let result1 = transport - .unregister_listener(&uri, None, listener.clone()) - .await; - assert!(result1.is_ok(), "First unregister should succeed"); - - let result2 = transport - .unregister_listener(&uri, None, listener.clone()) - .await; - assert!(result2.is_ok(), "Second unregister should succeed as no-op"); -} + #[test] + fn test_fail_missing_source_error() { + let uuri = UUri::new(); + let sink = test_uri("device1", 0x0004, 0x03AB, 0x03, 0x0000); + let result = Iceoryx2Transport::compute_service_name_from_uris(&uuri, Some(&sink)); + assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT)); + } -#[tokio::test] -async fn test_unregister_cycle() { - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::time::Duration; + #[tokio::test] + async fn test_register_listener_creates_subscriber() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener = Arc::new(MockUListener::new()); - let transport = Iceoryx2Transport::new().unwrap(); - let uri = UUri::try_from_parts(&format!("vehicle{}", std::process::id()), 0x123, 1, 0x9000) - .unwrap(); + let result = transport + .register_listener(&uri, None, listener.clone()) + .await; + assert!(result.is_ok(), "Listener registration should succeed"); + } - struct CountingListener { - count: AtomicUsize, + #[tokio::test] + async fn test_register_duplicate_listeners() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener1 = Arc::new(MockUListener::new()); + let listener2 = Arc::new(MockUListener::new()); + + let result1 = transport + .register_listener(&uri, None, listener1.clone()) + .await; + assert!( + result1.is_ok(), + "First listener registration should succeed" + ); + + let result2 = transport + .register_listener(&uri, None, listener2.clone()) + .await; + assert!( + result2.is_ok(), + "Second listener registration should succeed" + ); } - #[async_trait::async_trait] - impl UListener for CountingListener { - async fn on_receive(&self, _msg: UMessage) { - self.count.fetch_add(1, Ordering::SeqCst); - } + #[tokio::test] + async fn test_unregister_listener_cleanup() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener = Arc::new(MockUListener::new()); + + transport + .register_listener(&uri, None, listener.clone()) + .await + .unwrap(); + + let result = transport + .unregister_listener(&uri, None, listener.clone()) + .await; + assert!(result.is_ok(), "Listener unregistration should succeed"); } - let listener = Arc::new(CountingListener { - count: AtomicUsize::new(0), - }); + #[tokio::test] + async fn test_unregister_nonexistent_listener() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener = Arc::new(MockUListener::new()); + + let result = transport + .unregister_listener(&uri, None, listener.clone()) + .await; + assert!( + result.is_ok(), + "Unregistering non-existent listener should succeed as no-op" + ); + } - transport - .register_listener(&uri, None, listener.clone()) - .await - .unwrap(); + #[tokio::test] + async fn test_multiple_unregisters() { + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts("vehicle", 0x123, 1, 0x456).unwrap(); + let listener = Arc::new(MockUListener::new()); + + transport + .register_listener(&uri, None, listener.clone()) + .await + .unwrap(); + + let result1 = transport + .unregister_listener(&uri, None, listener.clone()) + .await; + assert!(result1.is_ok(), "First unregister should succeed"); + + let result2 = transport + .unregister_listener(&uri, None, listener.clone()) + .await; + assert!(result2.is_ok(), "Second unregister should succeed as no-op"); + } - tokio::time::sleep(Duration::from_millis(100)).await; + #[tokio::test] + async fn test_unregister_cycle() { + struct CountingListener { + count: AtomicUsize, + } - let message = UMessageBuilder::publish(uri.clone()).build().unwrap(); - transport.send(message.clone()).await.unwrap(); + #[async_trait::async_trait] + impl UListener for CountingListener { + async fn on_receive(&self, _msg: UMessage) { + self.count.fetch_add(1, Ordering::SeqCst); + } + } - tokio::time::sleep(Duration::from_millis(100)).await; + let transport = Iceoryx2Transport::new().unwrap(); + let uri = UUri::try_from_parts(&format!("vehicle{}", std::process::id()), 0x123, 1, 0x9000) + .unwrap(); - let count_before_unregister = listener.count.load(Ordering::SeqCst); - assert!( - count_before_unregister >= 1, - "Should have received at least one message" - ); + let listener = Arc::new(CountingListener { + count: AtomicUsize::new(0), + }); - transport - .unregister_listener(&uri, None, listener.clone()) - .await - .unwrap(); + transport + .register_listener(&uri, None, listener.clone()) + .await + .unwrap(); - tokio::time::sleep(Duration::from_millis(200)).await; + tokio::time::sleep(Duration::from_millis(100)).await; - for _ in 0..3 { + let message = UMessageBuilder::publish(uri.clone()).build().unwrap(); transport.send(message.clone()).await.unwrap(); - tokio::time::sleep(Duration::from_millis(50)).await; - } - tokio::time::sleep(Duration::from_millis(200)).await; + tokio::time::sleep(Duration::from_millis(100)).await; - let count_after_unregister = listener.count.load(Ordering::SeqCst); - assert_eq!( - count_before_unregister, count_after_unregister, - "Should not receive messages after unregister. Before: {}, After: {}", - count_before_unregister, count_after_unregister - ); -} - -#[test] -//both source and sink have resource ID equal to 0 -// .specitem[dsn~up-attributes-request-source~1] -// .specitem[dsn~up-attributes-request-sink~1] -// .specitem[dsn~up-attributes-response-source~1] -// .specitem[dsn~up-attributes-response-sink~1] -fn test_fail_resource_id_error() { - let source = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000); - let sink = test_uri("device1", 0x0004, 0x3AB, 0x3, 0x0000); - let result = Iceoryx2Transport::compute_service_name(&source, Some(&sink)); - assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT)); -} + let count_before = listener.count.load(Ordering::SeqCst); + assert!(count_before >= 1); -#[test] -//source has resource id=0 but missing sink -// .specitem[dsn~up-attributes-request-sink~1] -// .specitem[dsn~up-attributes-request-source~1] -fn test_fail_missing_sink_error() { - let source = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000); - let result = Iceoryx2Transport::compute_service_name(&source, None); - assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT)); -} + transport + .unregister_listener(&uri, None, listener.clone()) + .await + .unwrap(); -#[test] -//missing source URI -// .specitem[dsn~up-attributes-request-source~1] -// .specitem[dsn~up-attributes-response-source~1] -// .specitem[dsn~up-attributes-notification-source~1] -fn test_fail_missing_source_error() { - let uuri = UUri::new(); - let sink = test_uri("device1", 0x0004, 0x3AB, 0x3, 0x000); - let result = Iceoryx2Transport::compute_service_name(&uuri, Some(&sink)); - assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT)); -} + for _ in 0..3 { + transport.send(message.clone()).await.unwrap(); + tokio::time::sleep(Duration::from_millis(50)).await; + } + tokio::time::sleep(Duration::from_millis(200)).await; + let count_after = listener.count.load(Ordering::SeqCst); + assert_eq!( + count_before, count_after, + "Should not receive messages after unregister" + ); + } +}