# Ord, PartialOrd, Eq, PartialEq, Confusion, TotalConfusion

I have a type that represents distances:

``````#[derive(Clone, Debug, PartialEq)]
enum MeasurementSystem {
Imperial,
Metric
}

#[derive(Clone, Debug)]
pub struct Distance {
units: f64,
system: MeasurementSystem
}
``````

In my code, i’d like for `Distance` structs representing 1 meter and its equivalent in feet to equal. I’d also like to iterate over lists of items with distances, sorting them by distance.

In looking at comparison structs, I see `Eq`, `PartialEq`, `Ord` and `PartialOrd`. What would be the least I’d need to implement to get this working?

Assume the presence of a `to` method on `Distance` which mutably converts it to the specified system. There’s probably a more efficient way to do this, but for now I’m cloning distances, converting them to metric, and checking them that way. Here’s my current PartialEq implementation:

``````impl PartialEq for Distance {
fn eq(&self, other: &Distance) -> bool {
use MeasurementSystem::*;
let mut d1 = self.clone();
d1.to(Metric);
let mut d2 = other.clone();
d2.to(Metric);
d1.units == d2.units
}
}```

But I don't know if that is needed, or if I could do something similar with PartialOrd, like so:

``````

impl PartialOrd for Distance {
fn partial_cmp(&self, other: &Distance) -> Option {
use MeasurementSystem::*;
let mut d1 = self.clone();
d1.to(Metric);
let mut d2 = other.clone();
d2.to(Metric);
d1.units.partial_cmp(&d2.units)
}
}

``````
Thanks.``````

Have you tried taking inspiration from the `units` crate?
This helps with extactly this usecase.

Its trick is to have different types/impls for each measurement system, so you can let the typesystem figure out which comparison to use, instead of doing it dynamically.

After all, the defining feature of Rust is to do as much as possible statically.

1 Like

The crate is almost 3 years old. Does it still comply with current rust development?

1 Like

Thats why I said “inspiration”
The idea to use a single Type per measurement system, instead of a single type with runtime disambiguation, as OP currently has, should really simplify things, because it makes the conversions more explicit.

Right now, a `Distance` can be anything (Imperial, Metric, Quatloo’s), and that makes the single `Distance`-vs-`Distance` comparator complicated, especially because it has to do runtime disambiguation based on the `Distance.system` field.

If we expose the `MeasurementSystem` to Rust’s compiler, as `MetricDistrance`, `ImperialDistance`, `MartianDistance` types, this allows you to define (far simpler) different `Eq` Impls for the different combinations.

1 Like

https://ferrisellis.com/posts/rust-implementing-units-for-types/ is a good blog on doing something similar and can be used for inspiration as well.

1 Like

That’s nice, thanks, I’ll look into it! I was actually thinking of
typing things more strictly later, but figured I’d introduce that more

1 Like

Is there a process for people to declare a crate stalled such that new people can take it over rather than creating a new package based on it? Is it just using the GitHub repository to get the original author to pass it on?

1 Like

More recent and more full-featured crates are `uom` and `dimensioned`.

1 Like

I can’t seem to find uon, do you have a link? Thanks!

That’s an `M` not an `N` it’s at https://crates.io/crates/uom

1 Like

Ah, text-to-speech fail, Ns and Ms sound a lot alike at high speeds.
Thanks for catching that.

Thanks! I didn’t know about those!

For completeness sake, also the link to `dimensioned`:

https://crates.io/crates/dimensioned