Camden Narzt
Camden Narzt

Reputation: 2013

Can I make this assertion generic in Rust?

I'm trying to make an assertion that the type returned by a function in someone else's crate is big enough, and don't feel like changing my code if they change theirs to something that's still ok.

Here's a simplified version of what I'm trying to do (playground):

const NANOSECONDS_IN_DAY:f64 = 8.64E13;
trait HasMax<T> {
    fn max_value() -> T;
}
fn max_of<T:HasMax>(_: &T) -> T {
    T::max_value()
}
fn main() {
    let mv = max_of(&1f64);
    assert!(mv > NANOSECONDS_IN_DAY, "type is too small");
}

However I get the following error:

<anon>:5:13: 5:19 error: wrong number of type arguments: expected 1, found 0 [E0243]
<anon>:5 fn max_of<T:HasMax>(_: &T) -> T {
                     ^~~~~~

Upvotes: 1

Views: 506

Answers (2)

Camden Narzt
Camden Narzt

Reputation: 2013

extern crate num;
extern crate time;

#[cfg(test)]
mod tests {
    use num::Bounded;
    use time::{self,Tm};
    #[test]
    fn size_test() {
        let NANOSECONDS_IN_DAY:f64 = 8.64E13;
        fn max_of<T:Bounded>(_: T) -> T {
            T::max_value()
        }
        let type_v = time::Duration::zero().num_nanoseconds().unwrap();
        let mv = max_of(type_v);
        assert!(mv as f64 > NANOSECONDS_IN_DAY, "type is too small");
    }
}

This works.

Upvotes: 1

Dietrich Epp
Dietrich Epp

Reputation: 213817

Trying to make your code work in spite of unknown future breaking API changes in a library you are using is misguided at best. The short answer is that if the API of a library you are using changes, it is better that your code will fail to compile instead of failing in some more subtle or difficult to detect way. But I can answer why your code isn't compiling.

The problem is in your trait definition, which uses generics. Your trait should be HasMax, not HasMax<T>.

const NANOSECONDS_IN_DAY:f64 = 8.64E13;
trait HasMax {
    fn max_value() -> Self;
}
fn max_of<T:HasMax>(_: &T) -> T {
    T::max_value()
}
impl HasMax for f64 {
    fn max_value() -> Self {
        std::f64::MAX
    }
}
fn main() {
    let mv = max_of(&1f64);
    assert!(mv > NANOSECONDS_IN_DAY, "type is too small");
}

Upvotes: 2

Related Questions