From 5428646d9bafc21b51520f1fdd7fc5f7b3021139 Mon Sep 17 00:00:00 2001 From: Niwaka <61189782+NiwakaDev@users.noreply.github.com> Date: Mon, 30 Jan 2023 03:45:52 +0900 Subject: [PATCH] Optimize `RustStr`'s `Equatable` implementation (#151) --- .../StringTests.swift | 21 +++++++++++++++++++ .../src/generate_core/rust_string.c.h | 3 ++- .../src/generate_core/string.swift | 5 +---- src/std_bridge.rs | 2 ++ src/std_bridge/string.rs | 17 +++++++++++++++ 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/StringTests.swift b/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/StringTests.swift index 35403ed2..faebb781 100644 --- a/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/StringTests.swift +++ b/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/StringTests.swift @@ -46,5 +46,26 @@ class StringTests: XCTestCase { "hi" ) } + + func testRustStrEqualityOperator() throws { + XCTContext.runActivity(named: "Should be equal"){ + _ in + let hello1 = create_string("hello") + let hello2 = create_string("hello") + XCTAssertEqual(hello1.as_str(), hello2.as_str()) + } + XCTContext.runActivity(named: "Should not be equal"){ + _ in + //Not equal length + let hi = create_string("hi") + let hello = create_string("hello") + XCTAssertNotEqual(hi.as_str(), hello.as_str()) + + //Equal length + let foo = create_string("foo") + let bar = create_string("bar") + XCTAssertNotEqual(foo.as_str(), bar.as_str()) + } + } } diff --git a/crates/swift-bridge-build/src/generate_core/rust_string.c.h b/crates/swift-bridge-build/src/generate_core/rust_string.c.h index 3e27ae71..c8d85cf2 100644 --- a/crates/swift-bridge-build/src/generate_core/rust_string.c.h +++ b/crates/swift-bridge-build/src/generate_core/rust_string.c.h @@ -15,4 +15,5 @@ void* __swift_bridge__$RustString$new(void); void* __swift_bridge__$RustString$new_with_str(struct RustStr str); uintptr_t __swift_bridge__$RustString$len(void* self); struct RustStr __swift_bridge__$RustString$as_str(void* self); -struct RustStr __swift_bridge__$RustString$trim(void* self); \ No newline at end of file +struct RustStr __swift_bridge__$RustString$trim(void* self); +bool __swift_bridge__$RustStr$partial_eq(struct RustStr lhs, struct RustStr rhs); diff --git a/crates/swift-bridge-build/src/generate_core/string.swift b/crates/swift-bridge-build/src/generate_core/string.swift index 4f1f6f74..bc8a889f 100644 --- a/crates/swift-bridge-build/src/generate_core/string.swift +++ b/crates/swift-bridge-build/src/generate_core/string.swift @@ -27,10 +27,7 @@ extension RustStr: Identifiable { } extension RustStr: Equatable { public static func == (lhs: RustStr, rhs: RustStr) -> Bool { - // TODO: Rather than compare Strings, we can avoid allocating by calling a function - // on the Rust side that compares the underlying byte slices. - return - lhs.toString() == rhs.toString() + return __swift_bridge__$RustStr$partial_eq(lhs, rhs); } } diff --git a/src/std_bridge.rs b/src/std_bridge.rs index 4f31318a..24091b0e 100644 --- a/src/std_bridge.rs +++ b/src/std_bridge.rs @@ -1,3 +1,5 @@ +//! The corresponding C and Swift code can be found in +//! crates/swift-bridge-build/src/generate_core/* #![allow(missing_docs)] pub mod option; diff --git a/src/std_bridge/string.rs b/src/std_bridge/string.rs index 54d34286..387e5e55 100644 --- a/src/std_bridge/string.rs +++ b/src/std_bridge/string.rs @@ -1,3 +1,5 @@ +//! The corresponding C and Swift code can be found in +//! crates/swift-bridge-build/src/generate_core/rust_string.{c.h,swift} pub use self::ffi::*; #[swift_bridge_macro::bridge(swift_bridge_path = crate)] @@ -80,3 +82,18 @@ impl RustStr { } } } + +impl PartialEq for RustStr { + fn eq(&self, other: &Self) -> bool { + unsafe { + std::slice::from_raw_parts(self.start, self.len) + == std::slice::from_raw_parts(other.start, other.len) + } + } +} + +#[export_name = "__swift_bridge__$RustStr$partial_eq"] +#[allow(non_snake_case)] +pub extern "C" fn __swift_bridge__RustStr_partial_eq(lhs: RustStr, rhs: RustStr) -> bool { + lhs == rhs +}