Trait Into is not convenient.
Introduction
One of the most frequently used scenarios with trait Into is converting one type into another.
// point is of type Point
let vector: Vector = point.into();
This code works thanks to the automatic type determination mechanism. In this case, the Vector type is explicitly annotated, and the Into trait uses the corresponding implementation of Into for Point.
Problem
However, there are situations when automatic type determination does not work.
For example: SomeOfVector::from(point.into())
In such cases, it is necessary to explicitly specify the particular implementation of Into for Point:
SomeOfVector::from(<Point as Into<Vector>>::into(point))
This expression turns out to be redundant and difficult to read.
Solution
To simplify usage, one can shift the responsibility for specifying the particular implementation of Into from the trait signature to the method into signature. This is also semantically more correct. Instead of:
pub trait Into<T> {
fn into(self) -> T;
}
One should use:
pub trait Into {
fn into<I: From<Self>>(self) -> I
where
Self: Sized;
}
Just like in the standard implementation, it is necessary to implement Into for each type that has a From implementation:
impl<F> Into for F {
fn into<I: From<F>>(self) -> I {
I::from(self)
}
}
Now type conversion becomes simpler and cleaner for any usage scenarios:
let vector: Vector = point.into();
let vector = point.into::<Vector>();
SomeOfVector::from(point.into::<Vector>())