Warp easy way to terminate routes

let index = warp::path::end()
        .and(warp::get())
        .and_then(mid1)
        .and_then(mid2);

warp::serve(index).run(([127, 0, 0, 1], 3000)).await;

async fn mid1() -> Result<String, warp::Rejection> {
    let allow = false;

    if allow {
        return Ok("Hello".to_owned());
    }

    // Trying block here & do not send the request to next function (mid2)
    Err(warp::reply::with_status("Error", warp::http::StatusCode::NOT_FOUND))
}

async fn mid2<T>(_: T) -> Result<impl warp::Reply, warp::Rejection> {
    Ok(warp::reply::with_status(
        "World",
        warp::http::StatusCode::OK,
    ))
}

For future if anyone confuse, here is the entire code.

use warp::http::StatusCode;
use warp::reject::Reject;
use warp::{reject, Filter, Rejection, Reply};

const ALLOW: bool = false;

#[tokio::main]
async fn main() {
    let index = warp::path::end()
        .and(warp::get())
        .and_then(mid1)
        .and_then(mid2)
        .recover(mid3);

    warp::serve(index).run(([127, 0, 0, 1], 3000)).await;
}

async fn mid1() -> Result<String, Rejection> {
    if ALLOW {
        return Ok("Hello".to_owned());
    }

    Err(reject::custom(ErrorHandler {
        code: StatusCode::UNAUTHORIZED,
        message: "Not Allowed".to_string(),
    }))
}

async fn mid2(s: String) -> Result<impl Reply, Rejection> {
    Ok(warp::reply::with_status(
        format!("{} World", s),
        warp::http::StatusCode::OK,
    ))
}

async fn mid3(rej: Rejection) -> Result<impl Reply, Rejection> {
    let mut code: StatusCode = StatusCode::NOT_FOUND;
    let mut message: String = "Not Found".to_owned();

    if let Some(r) = rej.find::<ErrorHandler>() {
        code = r.code;
        message = r.message.to_owned();
    }

    Ok(warp::reply::with_status(message, code))
}

#[derive(Debug)]
struct ErrorHandler {
    code: StatusCode,
    message: String,
}

impl Reject for ErrorHandler {}