UniFFI traits¶
Some Rust standard traits can be exported, and are mapped onto the matching Kotlin members. This works on objects, records and enums.
| Rust trait | Kotlin |
|---|---|
Display |
toString() |
Debug |
toString(), if there is no Display |
Eq |
equals(other) |
Hash |
hashCode() |
Ord |
compareTo(other), and the class implements Comparable |
Each of these members calls into Rust, so the Rust implementation decides the result.
Exporting¶
With proc-macros, list the traits in #[uniffi::export(...)] on the type. The type must implement
them:
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, uniffi::Object)]
#[uniffi::export(Debug, Display, Eq, Hash, Ord)]
pub struct Version {
major: u32,
minor: u32,
}
impl std::fmt::Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}", self.major, self.minor)
}
}
In UDL, use the Traits attribute:
[Traits=(Display, Debug, Eq, Hash, Ord)]
interface Version {
constructor(u32 major, u32 minor);
};
val a = Version(1u, 2u)
val b = Version(1u, 10u)
"$a" // "1.2"
a == Version(1u, 2u) // true, compared by Rust
listOf(b, a).sorted() // [1.2, 1.10]
Records and enums¶
Records and enums are data classes, which already have equals, hashCode and toString.
Exporting the traits replaces those with the Rust implementations.
Fieldless enums become Kotlin enum classes, where equals, hashCode and compareTo are final.
For them only toString is generated. Kotlin's built-in behaviour matches a derived Rust
implementation, except that compareTo uses declaration order, while Rust's derived Ord uses
explicit discriminants if there are any.