I wanted to provide some feedback on my
I wanted to provide some feedback on my use of UniFFI in this POC. I decided to go with UniFFI primarily because it significantly reduces the complexity and workload involved in manual implementation. Additionally, the recent async support through the foreign language executor is a great advantage IMO. Another beneficial feature is the generation of foreign language bindings.
UniFFI is used by Mozilla for some of their projects (one example: https://github.com/mozilla/application-services) and Matrix (for their client SDK at https://github.com/matrix-org/matrix-rust-sdk), among others.
UniFFI handle data exchange with foreign languages by "serializing" the data (see: https://github.com/mozilla/uniffi-rs/blob/main/docs/adr/0002-serialize-complex-datatypes.md). For primitive types it's a simple cast, but for complex types it creates a buffer. For instance, a
Vec
is serialized by storing the length of the vector as the first bytes and the remaining data after that.
One limitation I encountered is the lack of native support for BTreeMap
and BTreeSet
. However, I managed to make it work by leveraging the experimental proc-macro feature. Additionally, I have a question: Did you choose to use BTreeXXX collections not because you needed a binary tree, but rather because implementing Hash
for Value
would have required to implement Hash
for HashMap<String, Value>
, and HashMap<Value, Value>
or there is another reason? (That's the reason I preferred to use BTree
, but HashMap
would have been easier since it's a built-in UniFFI type)
I believe UniFFI is not perfect but it's the best solution I've found thus far, except building everything from scratch...5 Replies
Hi. The main motivation was to implement
Ord
for Value
, but it is likely that HashMap
could have worked as well by deriving Hash
. Both are in std::collections. Open to feedback and input.Ok, I was wondering if there was a need for
Ord
because I thought it was not necessary to have this for Value but it seems I didn't dig enough, thanks for the answer 👍
Yes I could implement Hash
but for a HashMap
it becomes tricky if I'm correct, because you can't derive Hash
for HashMap
since automatic derive will not be able to ensure a reproductive way to create the hash because of the unordered nature of HashMap
but you can implement it manually to ensure a reproductive way to hash the HashMap
but I chose the other path.yep - deriving Hash is not so straightforward - would have to manually do it for HashMap. We went the other route. Deriving Ord is also not straightforward because
f64
is not Ord
, but there's a way to do it which we implemented.https://github.com/get-convex/convex-rs/blob/main/src/value/sorting.rs in case you hadn't seen it yet.
GitHub
convex-rs/src/value/sorting.rs at main · get-convex/convex-rs
Rust client library for Convex. Contribute to get-convex/convex-rs development by creating an account on GitHub.
Yes I saw that, I used the
ordered-float
crate for that if you're interested (can also help to impl Hash
for f64 which is not straightforward too)
https://crates.io/crates/ordered-float