0
votes

I am making a trait to define a distance in a metric space like:

trait Metric<T> {
    fn distance(o1: &T, o2: &T) -> f64;
}

and I want that any implementation satisfy some properties, for example:

distance(o, o) = 0.0

Exist a way in rust to enforce that?

1
I don't think there is, you could make some sort of guard on the return type but it's not very practical at some point it's the responsibility of the implementation to be correct. Have unit test etc.Stargateur
You could use assert_eq!, or return a Option/Result if the distance is not valid.hellow

1 Answers

1
votes

You can use the trait_tests crate, though I do believe the crate is merely an experiment, so there may be rough edges. Specifically, I couldn't figure out how to actually test all implementations of Metric<T>, rather only for a concrete type, Metric<i32>.

For your example:

use trait_tests::*;

pub trait Metric<T> {
    fn distance(o1: &T, o2: &T) -> f64;
}

#[trait_tests]
pub trait MetricTests: Metric<i32> {
    fn test_distance() {
        // These could possibly be extended using quickcheck or proptest
        assert!(Self::distance(&42, &42) == 0.0);
    }
}

struct CartesianPlane {}

#[test_impl]
impl Metric<i32> for CartesianPlane {
    fn distance(o1: &i32, o2: &i32) -> f64 {
        (*o2 - *o1) as f64
    }
}

Then cargo test should include the auto-generated test for the implementors of the trait that are annotated with #[test_impl].