You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: main.rs
    path of file: ./repos/gotham/examples/middleware/multiple_pipelines/src
    
    the code of the file until where you have to start completion: //! Provides examples of using multiple middleware pipelines for different routes.
//!
//! We'll create an app with a few different routes that need
//! different combinations of middleware.
//!
//! By default, we'll expect users to be logged in, using a session middleware
//! to track client cookies.
//! On the homepage, however, we don't want users logged in, so we'll override
//! this path to not use any middleware.
//! Our app also has some admin functionality, so we'll also override admin paths
//! to require an additional admin session.
//! Finally, our app exposes an JSON endpoint, which needs its own midd
    
fn router() -> Router {
    // The steps to build more advanced pipelines, as shown here, are a little
    // cumbersome - this is something we'd like review in the future.
    // We start by creating a (editable) pipeline set,
    // allowing us to add multiple pipelines of middleware.
    let pipelines = new_pipeline_set();
    // We can then create a pipeline - here with only one middleware for
    // our default sessions, but of course any number could be added.
    // This creates a default in-memory session store for our `Session` struct.
    let (pipelines, default) = pipelines.add(
        new_pipeline()
            .add(NewSessionMiddleware::default().with_session_type::<Session>())
            .build(),
    );
    // Similarly, we want a separate session middleware for our admin sessions.
    let (pipelines, extended) = pipelines.add(
        new_pipeline()
            .add(NewSessionMiddleware::default().with_session_type::<AdminSession>())
            .build(),
    );
    // Before we can use a pipeline set, we have to 'freeze' it. This returns a
    // version of it that is immutable, and can be used by our router to handle requests.
    let pipeline_set = finalize_pipeline_set(pipelines);

    // Next, we can chain together pipelines - in this case our default chain only
    // has our default pipeline, but our extended chain joins our extended 'admin'
    // pipeline onto the default chain - so middlewares in both pipelines will be
    // called in that chain.
    let default_chain = (default, ());
    let extended_chain = (extended, default_chain);

    // Finally, for our API, we can give it its own router and pipeline
    // altogether, which will be nested within our main router below.
    let (api_chain, api) = single_pipeline(new_pipeline().add(ApiMiddleware).build());
    let api_router = build_router(api_chain, api, |route| {
        route.get("/").to(api_handler);
    });

    // We build our router - giving it our default chain to apply to all routes
    // by default, unless overridden.
    build_router(default_chain, pipeline_set, |route| {
        // Requests dispatched to the '/account' route will only invoke one session
        // middleware which is the default behavior.
        route.get("/account").to(html_handler);

        // We override the base path to use an empty set of pipelines, skipping the session
        // middlewares.
        route.with_pipeline_chain((), |route| {
            route.get("/").to(html_handler);
        });

        // Requests for the admin handler will additionally invoke the admin session
        // middleware - as defined by our `extended_chain`.
        route.with_pipeline_chain(extended_chain, |route| {
            route.get("/admin").to(html_handler);
        });

        // Finally, we can mount our API router, telling it not to
        // pass down the default pipelines of the main router.
        // This achieves a similar result to the examples above, but
        // for more deeply nested routes, can be a neater way to
        // break things up. You can also use a `single_pipeline` per
        // router - avoiding the set up of a pipeline set as we did above.
        route
            .delegate_without_pipelines("/api")
            .to_router(api_router);
    })
}