I need to define a function that accepts T or Option<T> parameter. The Into works for basic literals but fails on custom objects implementing a trait (structs).
pub fn foo<T: Into<Option<u32>>>(v: T) {
v.into();
}
pub trait BarTrait {}
struct Bar {}
impl BarTrait for Bar {}
pub fn bar<T: Into<Option<impl BarTrait>>>(v: T) {
v.into();
}
fn main() {
foo(100u32); // OK
foo(Some(100u32)); // OK
foo(None); // OK
bar(Bar{}); // OK
bar(Some(Bar{})); // cannot infer type
bar(None); // cannot infer type
}
If you don't mind me asking, why in the world would you want to feed either a T or an Option<T> into the same function? The whole purpose of an Option is to give you an 'option' to avoid providing anything, or to provide some value that has to be there.
If you need to have 3 scenarios for inputs, just define your own custom enum with 3 separate possible values - and use those as an input, don't hack around with the arguments of a function to trick it into accepting more than what's needed.
I imagine it's just for convenience so you don't have to wrap the argument in Some, the same way some std functions take Into<String> args.
I'm not sure there's any great workaround when the Option is generic. You get similar issues with just a t: Option<T> as well, when you pass a None the compiler doesn't know what the generic type parameter should be.
@Ideator I totally forgot about that approach. I think this will work. The solution is so far the only way that covers cases with Vec and Option<Vec> variants that fail on From or TryFrom.