76 lines
1.3 KiB
Rust
76 lines
1.3 KiB
Rust
// build-pass
|
|
|
|
fn main() {
|
|
let mut log_service = LogService { inner: Inner };
|
|
log_service.call(());
|
|
}
|
|
|
|
pub trait Service<Request> {
|
|
type Response;
|
|
|
|
fn call(&mut self, req: Request) -> Self::Response;
|
|
}
|
|
|
|
pub struct LogService<S> {
|
|
inner: S,
|
|
}
|
|
|
|
impl<T, U, S> Service<T> for LogService<S>
|
|
where
|
|
S: Service<T, Response = U>,
|
|
U: Extension + 'static,
|
|
for<'a> U::Item<'a>: std::fmt::Debug,
|
|
{
|
|
type Response = S::Response;
|
|
|
|
fn call(&mut self, req: T) -> Self::Response {
|
|
self.inner.call(req)
|
|
}
|
|
}
|
|
|
|
pub struct Inner;
|
|
|
|
impl Service<()> for Inner {
|
|
type Response = Resp;
|
|
|
|
fn call(&mut self, req: ()) -> Self::Response {
|
|
Resp::A(req)
|
|
}
|
|
}
|
|
|
|
pub trait Extension {
|
|
type Item<'a>;
|
|
|
|
fn touch<F>(self, f: F) -> Self
|
|
where
|
|
for<'a> F: Fn(Self::Item<'a>);
|
|
}
|
|
|
|
pub enum Resp {
|
|
A(()),
|
|
}
|
|
|
|
impl Extension for Resp {
|
|
type Item<'a> = RespItem<'a>;
|
|
fn touch<F>(self, _f: F) -> Self
|
|
where
|
|
for<'a> F: Fn(Self::Item<'a>),
|
|
{
|
|
match self {
|
|
Self::A(a) => Self::A(a),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum RespItem<'a> {
|
|
A(&'a ()),
|
|
}
|
|
|
|
impl<'a> std::fmt::Debug for RespItem<'a> {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::A(arg0) => f.debug_tuple("A").field(arg0).finish(),
|
|
}
|
|
}
|
|
}
|