Trait bound covering T and Vec<T>

I've got a generic type that looks like this:

struct Foo<T: Fooable>
  where T: std::convert::From<T> for f64 {
  value: Option<T>,
}

I'd like to make it possible for T to be either T or Vec, but I'm not finding a way to structure the trait bounds correctly. With the code as above, I get this error from the compiler:

the trait std::convert::From<std::vec::Vec<FitSint32>> is not implemented for f64

I can't implement From for Vec because Vec is defined outside my crate.

I was hoping that there would be something in the trait bound syntax to express that T must implement bound A or bound B, but that doesn't appear to be a thing.

Is there a way to accomplish what I'm trying to do? TIA!

One way to model this situation could be to use an intermediate enum to discriminate between vec and atomic values. However, not sure if it is the most elegant or idiomatic solution here.

#[derive(Debug)]
enum VecOrAtom<'a, T> 
where T: std::convert::From<T> {
    Vector(&'a [T]),
    Atom(T)
}

#[derive(Debug)]
struct Foo<'a, T> {
  value: Option<VecOrAtom<'a, T>>,
} 


pub fn main() {
    let foo = Foo {
        value: Some(VecOrAtom::Atom(32))
    };
    println!("{:?}", foo);
    
    let bar = vec![1, 2, 3];
    let foo_v = Foo {
        value: Some(VecOrAtom::Vector(&bar))
    };
    println!("{:?}", foo_v);
}

There's no "A or B" in the trait system. You create a new trait C and implement it for A and B.

In this case you could also just write for non-generic &[T], because both T and Vec can be cast to &[T] at no cost.

4 Likes