Добрый день.
Я пытаюсь реализовать следующую схему:
let response: SomeResponse = client.handle(SomeRequest{...});
Трейт `Handler` содержит метод `handle`, который в качестве входного параметра принимает реализацию трейта `Request` и возвращает какое-то значение `T`. `Т` является параметром, потому что для одного и того же типа `R` в качестве результата могут быть возвращены значения различных типов (например `()` или `struct`).
pub trait Handler {
fn handle<T, R: Request>(&self, r: R) -> Result<T, R::Error>;
}
pub trait Request {
type Error;
fn handle<T, H: Handler>(&self, h: &H) -> Result<T, Self::Error>;
}
impl Handler for Client {
pub fn handle<R: Request>(&self, r: R) -> Result<(), R::Error> {
r.handle(self)
}
}
При обработке, каждый вариант перечисления `SomeRequest` может ветнуть свой тип (например `SomeResponse` или `()`), для этого метод `handle<T>` имеет параметр `T`.
pub enum SomeRequest {
Action,
Message,
...
}
pub struct SomeResponse {
...
}
impl ::Request for Request {
type Error = Error;
fn handle<T>(&self, handler: &::Client) -> Result<T, Error> {
Ok(match *self {
Request::Action => // должен возвращать структуру `SomeResponse`
Request::Message => // должен возвращать `()`
...
})
}
}
Но при попытке реализовать все это в том или ином виде, вылезают различные ошибки. Например:
error: conflicting implementations for trait
Если сделать ограничение, что определенная реализация `Request` будет возвращать один определенный тип, то проблема решается, но это не вариант...
1) Что-то я запутался с этипи параметрами. Методы трейта могут быть параметризованными? И если да, то как реализовать различные имплементации этого метода?
2) Подскажите пожалуйста как правильно осуществить подобную схему?