use serde::Deserialize;
use warp::{Filter, http::StatusCode, query, reject::Rejection, reply};
use crate::handlers::{self, UnexpectedError};
pub fn routes() -> impl Filter<Extract = impl warp::Reply, Error = std::convert::Infallible> + Clone
{
get_versions()
.or(get_all_versions())
.or(get_version())
.recover(handle_rejection)
}
fn get_versions() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path!("versions" / String / String)
.and(warp::get())
.and_then(handlers::get_versions)
}
#[derive(Deserialize)]
struct VersionsQuery {
all: Option<bool>,
platform: Option<String>,
}
fn get_all_versions() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path!("versions")
.and(query::<VersionsQuery>())
.and(warp::get())
.and_then(async |query: VersionsQuery| {
handlers::get_all_versions(query.all.unwrap_or(false), &query.platform).await
})
}
fn get_version() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path!("version" / String / String / String / String)
.and(warp::get())
.and_then(handlers::get_version)
}
async fn handle_rejection(err: Rejection) -> Result<impl warp::Reply, std::convert::Infallible> {
if err.is_not_found() {
Ok(reply::with_status("NOT_FOUND", StatusCode::NOT_FOUND))
} else if let Some(e) = err.find::<UnexpectedError>() {
eprintln!("unhandled rejection: {:?}", e.err);
Ok(reply::with_status(
"INTERNAL_SERVER_ERROR",
StatusCode::INTERNAL_SERVER_ERROR,
))
} else {
Ok(reply::with_status(
"INTERNAL_SERVER_ERROR",
StatusCode::INTERNAL_SERVER_ERROR,
))
}
}