#What traits should be implemented for Vec::binary_search ?
1 messages · Page 1 of 1 (latest)
Looking at the beginning of the impl block that the function is defined in, I see this:
impl<T> Vec<T>
where
T: IntoVal<Env, Val>,
{
That tells us T needs to impl the IntoVal trait, that is automatically implemented on any type defined with the contracttype attribute.
i.e.:
#[contracttype]
struct MyStruct {
General rule of thumb is that any SDK fn that takes a type probably requires the type to be a contracttype.
So, impl IntoVal for his struct (w/ contracttype) will then yield same results when binary_search-ing?
(as std::vec::Vec::binary_search I mean)
The struct implements IntoVal thanks to contracttype.
Here is a gist to reproduce the issue with a simple struct: https://gist.github.com/vinamogit/848b9c691b7b34761cc9ce1976d692e3
Giving the result:
input: [
TestStruct { foo: 50, bar: 20 },
TestStruct { foo: 15, bar: 20 },
TestStruct { foo: 30, bar: 40 },
TestStruct { foo: 30, bar: 20 }]
soroban: Vec(
Ok(TestStruct { foo: 15, bar: 20 }),
Ok(TestStruct { foo: 30, bar: 20 }),
Ok(TestStruct { foo: 50, bar: 20 }),
Ok(TestStruct { foo: 30, bar: 40 }))
std: [
TestStruct { foo: 15, bar: 20 },
TestStruct { foo: 30, bar: 20 },
TestStruct { foo: 30, bar: 40 },
TestStruct { foo: 50, bar: 20 }]
seems to be sorting bar then foo for soroban, but foo then bar for std 🙂
it looks like it for this struct at least. Maybe this is sorting by the Val or XDR representation.
It actually ignore the Ord implementation
3 is a charm. Perhaps add a 3rd one to confirm? foo, bar, deadbeef 🤣 ?
bug or not a bug?
I got a look at the host/env code for this, at some point it should call a object.cmp(other) but not sure about the types around. I'll need to look more.
This isn't a bug, although not intuitive. It's a result of structs being stored as maps, where the key is the field name, and Soroban Maps are ordered based on their keys, so the struct being ordered conceptually has the bar field first.