microversus_api 0.1.4

API interface for microversus
Documentation
mod error;
mod test;

pub use error::*;

use microversus_codex::{EventTag, LootAction, LootServiceResponse};
use reqwest::header::{ACCEPT, CONTENT_TYPE};
use reqwest::Client;
use serde::de::DeserializeOwned;
use serde::Serialize;

pub enum MicroversusEnv {
    Dev { world: String },
    Prod { world: String },
}

impl MicroversusEnv {
    pub fn url(&self, path: &str) -> String {
        match self {
            Self::Dev { world } => format!("https://{}.microversus.dev{}", world, path),
            Self::Prod { world } => format!("https://{}.microversus.run{}", world, path),
        }
    }
}

pub struct MicroversusApi {
    client: Client,
    env: MicroversusEnv,
}

impl MicroversusApi {
    pub fn new(world: &str, env: &str) -> Self {
        let client = Client::new();
        match env {
            "prod" => Self {
                client,
                env: MicroversusEnv::Prod {
                    world: world.into(),
                },
            },
            _ => Self {
                client,
                env: MicroversusEnv::Dev {
                    world: world.into(),
                },
            },
        }
    }

    pub async fn get_loot(
        &self,
        encounter_id: &str,
        tags: Option<Vec<EventTag>>,
    ) -> Result<LootServiceResponse, MicroversusApiError> {
        post_json(
            &self.client,
            &self.env.url("/loot"),
            &LootAction::GetResult {
                encounter_id: encounter_id.into(),
                tags,
                record_event: Some(true),
            },
        )
        .await
    }
}

async fn post_json<T: Serialize, R: DeserializeOwned>(
    client: &Client,
    url: &str,
    body: &T,
) -> Result<R, MicroversusApiError> {
    tracing::debug!("url: {} => {}", url, serde_json::to_string(&body).unwrap());

    let response = client
        .post(url)
        .header(ACCEPT, "application/json")
        .header(CONTENT_TYPE, "application/json")
        .json(body)
        .send()
        .await
        .map_err(MicroversusApiError::Request)?;

    response
        .error_for_status()?
        .json::<R>()
        .await
        .map_err(MicroversusApiError::Request)
}