I use the lib antonok/enum_dispatch to transform trait objects into concrete compound types. But I meet a strange behavior with TryInto
.
Here the macro implementation of core::convert::TryInto
expansion.rs#L147-157.
Here a simple implementation
use std::borrow::Borrow;
use enum_dispatch::enum_dispatch;
use strum_macros::{IntoStaticStr, EnumDiscriminants };
use serde::{Serialize, Deserialize};
use std::convert::{Infallible, TryInto};
use std::error::Error;
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
struct A {
a: i32
}
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
struct B {
b: i8
}
#[enum_dispatch]
#[derive(EnumDiscriminants, Serialize, Deserialize, Clone, Debug)]
#[strum_discriminants(derive(IntoStaticStr))]
#[strum_discriminants(name(ModelKind))]
enum Model {
B(B),
A(A)
}
impl Model {
fn vec_u8(&self) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::serde::encode_to_vec(self, bincode::config::standard())
}
fn from_vec_u8(v: &[u8]) -> Model {
let output = bincode::serde::decode_from_slice(v, bincode::config::standard()).unwrap();
output.0
}
}
#[enum_dispatch(Model)]
trait Action where Self: Serialize {
fn key(&self) -> i64;
}
impl Action for B {
fn key(&self) -> i64 {
self.b.into()
}
}
impl Action for A {
fn key(&self) -> i64 {
self.a.into()
}
}
And I want to create a method to unwrap the try_into()
method. This implementation work :
fn get_inner_by_param<T,M: TryInto<T, Error = &'static str>>(m: M) -> T {
m.try_into().unwrap()
}
...
let m = Model::A(A::default());
let a: A = get_inner_by_param(m);
// OK
But, If I call it inside a function with a generic output that's doesn't compile :
fn get_inner_by_param<T,M: TryInto<T, Error = &'static str>>(m: M) -> T {
m.try_into().unwrap()
}
...
fn get_inner<T>() -> T {
let model = Model::A(A::default());
get_inner_by_param(model)
}
// Error
error[E0271]: type mismatch resolving `<main3::tests::Model as TryInto<T>>::Error == &'static str`
--> src/main3.rs:63:9
|
63 | get_inner_by_param(model)
| ^^^^^^^^^^^^^^^^^^ expected `&str`, found enum `Infallible`
|
note: required by a bound in `get_inner_by_param`
--> src/main3.rs:57:43
|
57 | fn get_inner_by_param<T,M: TryInto<T, Error = &'static str>>(m: M) -> T {
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `get_inner_by_param`
Why does the error need to be Infallible
in this case? A solution does exist?