Search code examples
rustweb-frameworksiron

BeforeMiddleware implementation requires core::ops::Fn implementation


I am trying to implement the BeforeMiddleware trait for a struct I have. I have written the following code:

impl BeforeMiddleware for Auth {
    fn before(&self, _: &mut Request) -> IronResult<()> {
        println!("before called");
        Ok(())
    }

    fn catch(&self, _: &mut Request, err: IronError) -> IronResult<()> {
        println!("catch called");
        Err(err)
    }
}

I am getting the following error:

> cargo build
...
src/handlers/mod.rs:38:11: 38:28 error: the trait `for<'r, 'r, 'r> core::ops::Fn<(&'r mut iron::request::Request<'r, 'r>,)>` is not implemented for the type `auth::Auth` [E0277]
src/handlers/mod.rs:38     chain.link_before(auth);
                                 ^~~~~~~~~~~~~~~~~
src/handlers/mod.rs:38:11: 38:28 help: run `rustc --explain E0277` to see a detailed explanation
src/handlers/mod.rs:38:11: 38:28 error: the trait `for<'r, 'r, 'r> core::ops::FnOnce<(&'r mut iron::request::Request<'r, 'r>,)>` is not implemented for the type `auth::Auth` [E0277]
src/handlers/mod.rs:38     chain.link_before(auth);
                                 ^~~~~~~~~~~~~~~~~
src/handlers/mod.rs:38:11: 38:28 help: run `rustc --explain E0277` to see a detailed explanation
error: aborting due to 2 previous errors
...

But the documentation says the link_before function requires a BeforeMiddleware only.

Does anyone know why I am seeing this error and how to fix it?

EDIT:

I was actually using a static auth, after making it non-static the problem went away.


Solution

  • This works just fine:

    extern crate iron;
    
    use iron::{Chain, BeforeMiddleware, IronResult, Request, Response, IronError};
    use iron::status;
    
    struct Auth;
    
    impl BeforeMiddleware for Auth {
        fn before(&self, _: &mut Request) -> IronResult<()> {
            println!("before called");
            Ok(())
        }
    
        fn catch(&self, _: &mut Request, err: IronError) -> IronResult<()> {
            println!("catch called");
            Err(err)
        }
    }
    
    fn main() {
        fn hello_world(_: &mut Request) -> IronResult<Response> {
            Ok(Response::with((status::Ok, "Hello World!")))
        }
    
        let mut c = Chain::new(hello_world);
        let auth = Auth;
        c.link_before(auth);
    }
    

    This compiles against iron 0.2.6.