From c5ccd897caaec5bdab92a0bd8ebd23be7051e758 Mon Sep 17 00:00:00 2001 From: Kai Hudalla Date: Thu, 12 Feb 2026 09:32:33 +0100 Subject: [PATCH] [#296] Support comparison of UUri with URI strings Added `PartialEq<&str>` implementation for `UUri` to allow direct comparison between `UUri` instances and URI strings. This enhancement simplifies code that needs to compare URIs without requiring explicit conversion to `UUri`. Fixes #296 --- Cargo.lock | 27 +++++------ Cargo.toml | 3 +- src/umessage/umessagebuilder.rs | 2 +- src/umessage/umessagetype.rs | 4 +- src/uri.rs | 80 +++++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1916180..64dc55c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,9 +153,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cfg-if" @@ -329,9 +329,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" dependencies = [ "powerfmt", ] @@ -862,9 +862,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "object" @@ -1549,30 +1549,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -1723,6 +1723,7 @@ dependencies = [ "symphony", "test-case", "thiserror", + "time", "tokio", "tracing", "uriparse", diff --git a/Cargo.toml b/Cargo.toml index bffc8d7..73c9a97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ symphony = ["communication", "dep:serde", "dep:serde_json", "dep:symphony"] [dependencies] async-trait = { version = "0.1" } -bytes = { version = "1.10" } +bytes = { version = "1.11.1" } mediatype = "0.20" mockall = { version = "0.13", optional = true } protobuf = { version = "3.7.2", features = ["with-bytes"] } @@ -70,6 +70,7 @@ cucumber = { version = "0.21.1", features = ["output-junit"] } hex = { version = "0.4.3" } mockall = { version = "0.13.1" } test-case = { version = "3.3.1" } +time = { version = "0.3.47" } tokio = { version = "1.45.1", default-features = false, features = [ "macros", "rt", diff --git a/src/umessage/umessagebuilder.rs b/src/umessage/umessagebuilder.rs index 540b3fe..c60771e 100644 --- a/src/umessage/umessagebuilder.rs +++ b/src/umessage/umessagebuilder.rs @@ -339,7 +339,7 @@ impl UMessageBuilder { /// Sets the message's priority. /// /// If not set explicitly, the default priority as defined in the - /// [uProtocol specification](https://github.com/eclipse-uprotocol/up-spec/blob/main/basics/qos.adoc) + /// [uProtocol specification](https://github.com/eclipse-uprotocol/up-spec/blob/main/basics/upriority.adoc) /// is used. /// /// # Arguments diff --git a/src/umessage/umessagetype.rs b/src/umessage/umessagetype.rs index ada9122..aa3f208 100644 --- a/src/umessage/umessagetype.rs +++ b/src/umessage/umessagetype.rs @@ -91,8 +91,8 @@ mod tests { ) { let result = UMessageType::try_from_cloudevent_type(cloudevent_type); assert!(result.is_ok() == expected_message_type.is_some()); - if expected_message_type.is_some() { - assert_eq!(result.unwrap(), expected_message_type.unwrap()) + if let Some(message_type) = expected_message_type { + assert_eq!(result.unwrap(), message_type) } else { assert!(matches!( result.unwrap_err(), diff --git a/src/uri.rs b/src/uri.rs index 4cb6c65..4122921 100644 --- a/src/uri.rs +++ b/src/uri.rs @@ -293,6 +293,27 @@ impl Hash for UUri { impl Eq for UUri {} +impl PartialEq for UUri { + fn eq(&self, other: &str) -> bool { + match UUri::from_str(other) { + Ok(other_uri) => self.eq(&other_uri), + Err(_) => false, + } + } +} + +impl PartialEq<&str> for UUri { + fn eq(&self, other: &&str) -> bool { + self.eq(*other) + } +} + +impl PartialEq for UUri { + fn eq(&self, other: &String) -> bool { + self.eq(other.as_str()) + } +} + impl UUri { /// Serializes this UUri to a URI string. /// @@ -990,6 +1011,65 @@ mod tests { use super::*; use test_case::test_case; + #[test_case(UUri { + authority_name: "vin".into(), + ue_id: 0x0000_8000, + ue_version_major: 0x01, + resource_id: 0x0002, + ..Default::default() + }, + "//vin/8000/1/2" => true; + "succeeds for full URI with authority")] + #[test_case(UUri { + authority_name: "".into(), + ue_id: 0x0000_8000, + ue_version_major: 0x01, + resource_id: 0x0002, + ..Default::default() + }, + "up:/8000/1/2" => true; + "succeeds for URI without authority")] + #[test_case(UUri { + authority_name: "vin".into(), + ue_id: 0x0000_8000, + ue_version_major: 0x01, + resource_id: 0x0002, + ..Default::default() + }, + "//other-vin/8000/1/2" => false; + "fails for different authority")] + #[test_case(UUri { + authority_name: "vin".into(), + ue_id: 0x0000_8000, + ue_version_major: 0x01, + resource_id: 0x0002, + ..Default::default() + }, + "up://vin/18000/1/2" => false; + "fails for different entity ID")] + #[test_case(UUri { + authority_name: "vin".into(), + ue_id: 0x0000_8000, + ue_version_major: 0x01, + resource_id: 0x0002, + ..Default::default() + }, + "//vin/8000/2/2" => false; + "fails for different version")] + #[test_case(UUri { + authority_name: "vin".into(), + ue_id: 0x0000_8000, + ue_version_major: 0x01, + resource_id: 0x0002, + ..Default::default() + }, + "up://vin/8000/1/5" => false; + "fails for different resource ID")] + #[allow(clippy::cmp_owned)] + fn test_eq_with_str(uuri: UUri, uri_str: &str) -> bool { + uuri == uri_str && uuri == *uri_str && uuri == String::from(uri_str) + } + // [utest->dsn~uri-authority-name-length~1] // [utest->dsn~uri-host-only~2] #[test_case(UUri {