use http::header::{HeaderMap, HeaderValue, USER_AGENT};
use http::uri::Authority;
use crate::error::{self, Error};
use crate::types::id::{GameId, UserId};
use crate::types::{TargetPlatform, TargetPortal};
use super::host::Host;
use super::{Client, HDR_X_MODIO_PLATFORM, HDR_X_MODIO_PORTAL};
use super::service::Svc;
pub struct Builder {
host: Option<Host>,
api_key: Box<str>,
token: Option<Box<str>>,
headers: HeaderMap,
error: Option<Error>,
}
impl Builder {
pub fn new(api_key: String) -> Self {
Self {
host: None,
api_key: api_key.into_boxed_str(),
token: None,
headers: HeaderMap::new(),
error: None,
}
}
pub fn build(self) -> Result<Client, Error> {
if let Some(e) = self.error {
return Err(e);
}
let http = Svc::new();
let host = self.host.unwrap_or_default();
Ok(Client {
http,
host,
api_key: self.api_key,
token: self.token,
headers: self.headers,
})
}
pub fn token(mut self, token: String) -> Self {
self.token = Some(create_token(token));
self
}
pub fn use_default_env(mut self) -> Self {
self.host = Some(Host::Default);
self
}
pub fn use_test_env(mut self) -> Self {
self.host = Some(Host::Test);
self
}
pub fn game_host(mut self, game_id: GameId) -> Self {
self.host = Some(Host::Game(game_id));
self
}
pub fn user_host(mut self, user_id: UserId) -> Self {
self.host = Some(Host::User(user_id));
self
}
pub fn dynamic_game_host(mut self) -> Self {
self.host = Some(Host::Dynamic);
self
}
pub fn dynamic_game_host_with_custom<V>(mut self, host: V) -> Self
where
V: TryInto<Authority>,
V::Error: Into<http::Error>,
{
match host.try_into() {
Ok(host) => {
self.host = Some(Host::DynamicWithCustom(host));
}
Err(err) => {
self.error = Some(error::builder(err.into()));
}
}
self
}
pub fn host<V>(mut self, host: V) -> Self
where
V: TryInto<Authority>,
V::Error: Into<http::Error>,
{
match host.try_into() {
Ok(host) => {
self.host = Some(Host::Custom(host));
}
Err(err) => {
self.error = Some(error::builder(err.into()));
}
}
self
}
pub fn user_agent<V>(mut self, value: V) -> Self
where
V: TryInto<HeaderValue>,
V::Error: Into<http::Error>,
{
match value.try_into() {
Ok(value) => {
self.headers.insert(USER_AGENT, value);
}
Err(err) => {
self.error = Some(error::builder(err.into()));
}
}
self
}
pub fn target_platform(mut self, platform: TargetPlatform) -> Self {
match HeaderValue::from_str(platform.as_str()) {
Ok(value) => {
self.headers.insert(HDR_X_MODIO_PLATFORM, value);
}
Err(err) => {
self.error = Some(error::builder(err));
}
}
self
}
pub fn target_portal(mut self, portal: TargetPortal) -> Self {
match HeaderValue::from_str(portal.as_str()) {
Ok(value) => {
self.headers.insert(HDR_X_MODIO_PORTAL, value);
}
Err(err) => {
self.error = Some(error::builder(err));
}
}
self
}
}
pub(super) fn create_token(mut token: String) -> Box<str> {
if !token.starts_with("Bearer ") {
token.insert_str(0, "Bearer ");
}
token.into_boxed_str()
}
#[cfg(test)]
mod tests {
use super::create_token;
#[test]
fn test_create_token() {
assert_eq!("Bearer token", &*create_token("token".to_owned()));
assert_eq!("Bearer token", &*create_token("Bearer token".to_owned()));
}
}