uniffi-rs
uniffi-rs copied to clipboard
Crash when using `custom_type!`
The try_lift error is not re-thrown in the Swift binding, which causes crashes.
Use the examples/custom-types project as an example. Swift can pass Foundation.URL to Rust as url::Url. On Rust side, the try_lift implementation may return an error.
// `Url` gets converted to a `String` to pass across the FFI.
uniffi::custom_type!(Url, String, {
// Remote is required since `Url` is from a different crate
remote,
try_lift: |val| Ok(Url::parse(&val)?),
lower: |obj| obj.into(),
});
When Rust's try_lift fails to convert the URL string to a url::Url instance, the error was not re-thrown to Swift, and Swift code crashes.
Here is a diff to reproduce the issue:
diff --git a/examples/custom-types/src/lib.rs b/examples/custom-types/src/lib.rs
index 9747b5749..91ee0910d 100644
--- a/examples/custom-types/src/lib.rs
+++ b/examples/custom-types/src/lib.rs
@@ -87,6 +87,11 @@ pub fn get_custom_types_demo(v: Option<CustomTypesDemo>) -> CustomTypesDemo {
})
}
+#[uniffi::export]
+pub fn custom_types_url_length(url: Url) -> u64 {
+ url.as_str().len() as u64
+}
+
#[uniffi::export]
pub fn get_example_custom_type() -> ExampleCustomType {
ExampleCustomType("abadidea".to_string())
diff --git a/examples/custom-types/tests/bindings/test_custom_types.swift b/examples/custom-types/tests/bindings/test_custom_types.swift
index 97dea019c..e654b7d8a 100644
--- a/examples/custom-types/tests/bindings/test_custom_types.swift
+++ b/examples/custom-types/tests/bindings/test_custom_types.swift
@@ -23,4 +23,7 @@ do {
demo.timeIntervalSecDbl = Date(timeIntervalSince1970: 789.0)
demo.timeIntervalSecFlt = Date(timeIntervalSince1970: 111.0)
assert(demo == getCustomTypesDemo(demo: demo))
+
+ let url = URL(string: "abc")! // Not a valid `url::Url`
+ assert(customTypesUrlLength(url: url) == 3)
}