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: ad_hoc.rs
    path of file: ./repos/Rocket/core/lib/src/fairing
    
    the code of the file until where you have to start completion: use futures::future::{Future, BoxFuture, FutureExt};
use parking_lot::Mutex;

use crate::route::RouteUri;
use crate::{Rocket, Request, Response, Data, Build, Orbit};
use crate::fairing::{Fairing, Kind, Info, Result};

/// A ad-hoc fairing that can be created from a function or closure.
///
/// This enum can be used to create a fairing from a simple function or closure
/// without creating a new structure or implementing `Fairing` directly.
///
/// # Usage
///
/// Use [`AdHoc::on_ignite`], [`AdHoc::on_liftoff`], [`AdHoc::on_request()`], or
/// [`AdHoc::on_response()`] to create an `AdHoc` structure from a function or
/// closure. Then, simply attach the structure to the `Rocket` instance.
///
/// # Example
///
/// The following snippet creates a `Rocket` instance with two ad-hoc fairings.
/// The first, a liftoff fairing named "Liftoff Printer", simply prints a message
/// indicating that Rocket has launched. The second named "Put Rewriter", a
/// request fairing, rewrites the method of all requests to be `PUT`.
///
/// ```rust
/// use rocket::fairing::AdHoc;
/// use rocket::http::Method;
///
/// rocket::build()
///     .attach(AdHoc::on_liftoff("Liftoff Printer", |_| Box::pin(async move {
///         println!("...annnddd we have liftoff!");
///     })))
///     .attach(AdHoc::on_request("Put Rewriter", |req, _| Box::pin(async move {
///         req.set_method(Method::Put);
///     })));
/// ```
pub struct AdHoc {
    name: &'static str,
    kind: AdHocKind,
}

struct Once<F: ?Sized>(Mutex<Option<Box<F>>>);

impl<F: ?Sized> Once<F> {
    fn new(f: Box<F>) -> Self { Once(Mutex::new(Some(f))) }

    #[track_caller]
    fn take(&self) -> Box<F> {
        self.0.lock().take().expect("Once::take() called once")
    }
}

enum AdHocKind {
    /// An ad-hoc **ignite** fairing. Called during ignition.
    Ignite(Once<dyn FnOnce(Rocket<Build>) -> BoxFuture<'static, Result> + Send + 'static>),

    /// An ad-hoc **liftoff** fairing. Called just after Rocket launches.
    Liftoff(Once<dyn for<'a> FnOnce(&'a Rocket<Orbit>) -> BoxFuture<'a, ()> + Send + 'static>),

    /// An ad-hoc **request** fairing. Called when a request is received.
    Request(Box<dyn for<'a> Fn(&'a mut Request<'_>, &'a mut Data<'_>)
        -> BoxFuture<'a, ()> + Send + Sync + 'static>),

    /// An ad-hoc **response** fairing. Called when a response is ready to be
    /// sent to a client.
    Response(Box<dyn for<'r, 'b> Fn(&'r Request<'_>, &'b mut Response<'r>)
        -> BoxFuture<'b, ()> + Send + Sync + 'static>),

    /// An ad-hoc **shutdown** fairing. Called on shutdown.
    Shutdown(Once<dyn for<'a> FnOnce(&'a Rocket<Orbit>) -> BoxFuture<'a, ()> + Send + 'static>),
}

impl AdHoc {
    /// Constructs an `AdHoc` ignite fairing named `name`. The function `f` will
    /// be called by Rocket during the [`Rocket::ignite()`] phase.
    ///
    /// This version of an `AdHoc` ignite fairing cannot abort ignite. For a
    /// fallible version that can, see [`AdHoc::try_on_ignite()`].
    ///
    /// # Example
    ///
    /// ```rust
    /// use rocket::fairing::AdHoc;
    ///
    /// // The no-op ignite fairing.
    /// let fairing = AdHoc::on_ignite("Boom!", |rocket| async move {
    ///     rocket
    /// });
    
    
    pub fn uri_normalizer() -> impl Fairing {
        #[derive(Default)]
        struct Normalizer {
            routes: state::InitCell<Vec<crate::Route>>,
        }

        impl Normalizer {
            fn routes(&self, rocket: &Rocket<Orbit>) -> &[crate::Route] {
                self.routes.get_or_init(|| {
                    rocket.routes()
                        .filter(|r| r.uri.has_trailing_slash())
                        .cloned()
                        .collect()
                })
            }
        }

        #[crate::async_trait]
        impl Fairing for Normalizer {
            fn info(&self) -> Info {
                Info { name: "URI Normalizer", kind: Kind::Ignite | Kind::Liftoff | Kind::Request }
            }

            async fn on_ignite(&self, rocket: Rocket<Build>) -> Result {
                // We want a route like `/foo/<bar..>` to match a request for
                // `/foo` as it would have before. While we could check if a
                // route is mounted that would cause this match and then rewrite
                // the request URI as `/foo/`, doing so is expensive and
                // potentially incorrect due to request guards and ranking.
                //
                // Instead, we generate a new route with URI `/foo` with the
                // same rank and handler as the `/foo/<bar..>` route and mount
                // it to this instance of `rocket`. This preserves the previous
                // matching while still checking request guards.
                let normalized_trailing = rocket.routes()
                    .filter(|r| r.uri.metadata.dynamic_trail)
                    .filter(|r| r.uri.path().segments().num() > 1)
                    .filter_map(|route| {
                        let path = route.uri.unmounted().path();
                        let new_path = path.as_str()
                            .rsplit_once('/')
                            .map(|(prefix, _)| prefix)
                            .filter(|path| !path.is_empty())
                            .unwrap_or("/");

                        let base = route.uri.base().as_str();
                        let uri = match route.uri.unmounted().query() {
                            Some(q) => format!("{}?{}", new_path, q),
                            None => new_path.to_string()
                        };

                        let mut route = route.clone();
                        route.uri = RouteUri::try_new(base, &uri).ok()?;
                        route.name = route.name.map(|r| format!("{} [normalized]", r).into());
                        Some(route)
                    })
                    .collect::<Vec<_>>();

                Ok(rocket.mount("/", normalized_trailing))
            }

            async fn on_liftoff(&self, rocket: &Rocket<Orbit>) {
                let _ = self.routes(rocket);
            }

            async fn on_request(&self, req: &mut Request<'_>, _: &mut Data<'_>) {
                // If the URI has no trailing slash, it routes as before.
                if req.uri().is_normalized_nontrailing() {
                    return
                }

                // Otherwise, check if there's a route that matches the request
                // with a trailing slash. If there is, leave the request alone.
                // This allows incremental compatibility updates. Otherwise,
                // rewrite the request URI to remove the `/`.
                if !self.routes(req.rocket()).iter().any(|r| r.matches(req)) {
                    let normal = req.uri().clone().into_normalized_nontrailing();
                    warn!("Incoming request URI was normalized for compatibility.");
                    info_!("{} -> {}", req.uri(), normal);
                    req.set_uri(normal);
                }
            }
        }

        Normalizer::default()
    }