mod error;
pub use error::*;
use microversus_codex::{EncounterResult, EventTag, LootAction};
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::Dev {
world: world.into(),
},
},
_ => Self {
client,
env: MicroversusEnv::Prod {
world: world.into(),
},
},
}
}
pub async fn get_loot(
&self,
encounter_id: &str,
tags: Option<Vec<EventTag>>,
) -> Result<EncounterResult, 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> {
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)
}