I want to create a default implementation for a trait member function that deserializes into some type, returns the error making sure it is mappable to some other error type provided by the implementing party as an associated type.
Originally I tried making the transform
function generic over D returning Result<Self::Payload, D::Error >
with D bound to the Deserializer
trait but this is problematic for type inference as a default implementation. So I reached for E as a generic over the error type instead.
I expected this to work but when compiling I get the following error:
error[E0308]: mismatched types
--> src/main.rs:43:9
|
39 | fn transform<E>(&self, buf: &[u8]) -> Result<Self::Payload, E>
| - this type parameter ------------------------ expected `Result<SomePayload, E>` because of return type
...
43 | serde_json::from_slice(buf)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `E`, found struct `serde_json::Error`
|
= note: expected enum `Result<SomePayload, E>`
found enum `Result<_, serde_json::Error>`
Code:
use serde::Deserialize;
use serde_json::Error;
pub trait SomeTrait<'de> {
type Payload: Deserialize<'de>;
type Error;
fn accept(&self, msg: Result<Self::Payload, Self::Error>);
fn transform<E>(&self, buf: &[u8]) -> Result<Self::Payload, E>
where
Self::Error: From<E>;
fn default_impl(&self) {
let transformed = self.transform(&[]);
let transformed = transformed.map_err(Into::into);
self.accept(transformed);
}
}
#[derive(Deserialize)]
struct SomePayload;
enum SomeError {}
impl From<serde_json::Error> for SomeError {
fn from(_: Error) -> Self {
todo!()
}
}
struct SomeStruct;
impl<'de> SomeTrait<'de> for SomeStruct {
type Payload = SomePayload;
type Error = SomeError;
fn accept(&self, msg: Result<Self::Payload, Self::Error>) {}
fn transform<E>(&self, buf: &[u8]) -> Result<Self::Payload, E>
where
Self::Error: From<E>,
{
serde_json::from_slice(buf)
}
}
fn main() {
let s = SomeStruct;
s.default_impl();
}