#What traits should be implemented for Vec::binary_search ?

1 messages · Page 1 of 1 (latest)

dreamy mesa
#

Hi,
I'm trying to have a sorted Vec<Struct>, I've implemented Ord (and PartialOrd) for Struct.
The result is not sorted as expected, when I say expected I'm comparing to std::vec::Vec::binary_search.

Does soroban rely on other implementation?

verbal shuttle
#

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>,
{

Ref: https://github.com/stellar/rs-soroban-sdk/blob/71170fba76e1aa4d50224316f1157f0fb10e6d79/soroban-sdk/src/vec.rs#L835

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 {
GitHub

Rust SDK for Soroban Contracts. Contribute to stellar/rs-soroban-sdk development by creating an account on GitHub.

#

General rule of thumb is that any SDK fn that takes a type probably requires the type to be a contracttype.

trail citrus
#

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)

dreamy mesa
#

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 }]
trail citrus
dreamy mesa
#

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

trail citrus
#

3 is a charm. Perhaps add a 3rd one to confirm? foo, bar, deadbeef 🤣 ?

dreamy mesa
#

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.

verbal shuttle
#

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.