jvmvm-api 0.1.0

The API for the JVMVM
Documentation
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,
        ))
    }
}