Here is what I am trying to do:
use std::convert::{TryFrom, TryInto};
fn main() -> Result<(), CommonError> {
let input = String::from("this is a long string");
//This works fine
//note that it automatically converts the StringTooLongError -> CommonError
Ok(println!("{:?}", MyType::try_from(input)? ))
//that would have been better
//Ok(println!("{:?}", convert(input)? ))
}
//but this fails: the trait `std::convert::From<<impl TryInto<MyType> as
std::convert::TryInto<MyType>>::Error>` is not implemented for
`StringTooSmallError`
//why?
/*
fn convert(s: impl TryInto<MyType>) -> Result<MyType,
StringTooSmallError> {
Ok(s.try_into()?)
}
*/
#[derive(Debug)]
enum CommonError {
StringError
}
impl From<StringTooSmallError> for CommonError {
fn from(e: StringTooSmallError) -> Self {
CommonError::StringError
}
}
#[derive(Debug)]
struct MyType(String);
#[derive(Debug)]
struct StringTooSmallError;
/*impl std::fmt::Display for StringTooSmallError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "string is too small")
}
}
impl std::error::Error for StringTooSmallError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}*/
impl TryFrom<String> for MyType {
type Error = StringTooSmallError;
fn try_from(s: String) -> Result<Self, StringTooSmallError> {
let len = s.len();
match len {
0..=4 if len < 4 => Err(StringTooSmallError),
_ => Ok(MyType(s[..=5].to_owned()))
}
}
}
I think my problem is self explained in the code. Here is in play: Rust Playground
I thought that having specified the TryFrom, TryInto should come for free, but apparently it doesn't. I guess it would work in the case of From/Into, but I would really like to achieve the same easiness with the TryFrom/TryInto traits. Is it possible or should I just abandon my effort ?