mfs 0.2.1

Fetcher for scholarly metadata
use axum::{
    body::Body,
    extract::Path,
    response::{IntoResponse, Response},
    routing::get,
    Router,
};
use axum_extra::extract::Query;
use reqwest::StatusCode;
use serde::Deserialize;

use crate::{output::MetadataSource, publications::fetch_dois};

pub async fn handle_server_command(port: &Option<u16>) {
    let app = Router::new()
        .route("/", get(root))
        .route("/api/v1/pub/doi/{*doi}", get(single_doi));

    let listener =
        tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port.unwrap_or_else(|| 6789)))
            .await
            .unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn root() -> &'static str {
    "mfs 0.1.0"
}

#[derive(Debug, Deserialize)]
struct SingleDoiParams {
    #[serde(default)]
    source: Vec<MetadataSource>,
}

async fn single_doi(
    Path(doi): Path<String>,
    Query(params): Query<SingleDoiParams>,
) -> impl IntoResponse {
    let report = fetch_dois(&vec![doi], &params.source).await;

    match report.first() {
        Some(r) => r.clone().into_response(),
        None => Response::builder()
            .status(StatusCode::NOT_FOUND)
            .body(Body::from("Not found"))
            .unwrap(),
    }
}