Reputation: 57
I have Either
type:
enum Either<L, R> {
Left(L),
Right(R),
}
and i want to implement From
trait for both of it's variants:
impl<L, R> From<L> for Either<L, R> {
fn from(l: L) -> Self {
Self::Left(l)
}
}
impl<L, R> From<R> for Either<L, R> {
fn from(r: R) -> Self {
Self::Right(r)
}
}
and yes, obviously they overlaps. So the question is how to make Either
's L
and R
generic types not equal and implement both From
s? So that:
type EitherStringString = Either<String, String>; // compilation error, because `Either`'s `L` and `R` types are equal
type EitherStringInt = Either<String, i32>; // ok
#[test]
fn either_string_int_from_string() { // ok
let string: String = String::from("hello");
assert_eq!(
Either::<String, i32>::Left(string),
string.into()
);
}
#[test]
fn either_string_int_from_int() { // ok
let number: i32 = 42;
assert_eq!(
Either::<String, i32>::Right(number),
number.into()
);
}
"Prior art": negative_bounds
and negative_impls
features looks like this is the exact thing i need, but i can't figure out how to use them to achieve desired result. I tried:
#![feature(negative_bounds, negative_impls)]
trait LT {}
trait RT: !LT {}
// neither combination of this solves the issue
// impl<L: !RT> LT for L {}
// impl<L> !RT for L {}
// impl<R: !LT> RT for R {}
// impl<R> !LT for R {}
impl<L: LT, R: RT> From<L> for Either<L, R> {
fn from(l: L) -> Self {
Self::Left(l)
}
}
impl<L: LT, R: RT> From<R> for Either<L, R> {
fn from(r: R) -> Self {
Self::Right(r)
}
}
but this gives compilation error:
conflicting implementations of trait `From<_>` for type `either::Either<_, _>`
So how to implement From
for Either
?
Upvotes: 2
Views: 143