Skip to content

Commit

Permalink
move OpenShockAPI initialization into builder
Browse files Browse the repository at this point in the history
  • Loading branch information
999eagle committed Aug 16, 2024
1 parent 5ccf3da commit b489067
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 16 deletions.
86 changes: 70 additions & 16 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,45 @@ use reqwest::header;
use std::fmt::Debug;
use strum_macros::EnumString;

/// All methods contain an `Option<String>` to provide an alternate api key to use if it differs from the default
pub struct OpenShockAPI {
client: reqwest::Client,
base_url: String,
default_key: String,
/// Builder for [`OpenShockAPI`]
#[derive(Default)]
pub struct OpenShockAPIBuilder {
base_url: Option<String>,
default_key: Option<String>,
}

/// Which list of shockers to return
#[derive(EnumString, Debug)]
pub enum ListShockerSource {
Own,
Shared,
}
impl OpenShockAPIBuilder {
/// Create a new builder
pub fn new() -> Self {
Self::default()
}

/// set the base URL to use
///
/// this is optional and can be provided to use a self-hosted instance of the OpenShock API. if
/// left unset, the default (`https://api.openshock.app`) will be used.
pub fn with_base_url(mut self, base_url: String) -> Self {
self.base_url = Some(base_url);
self
}

/// set the API token to use
///
/// this must be provided
pub fn with_default_api_token(mut self, default_api_token: String) -> Self {
self.default_key = Some(default_api_token);
self
}

/// check parameters and build an instance of [`OpenShockAPI`]
pub fn build(self) -> Result<OpenShockAPI, Error> {
let base_url = self
.base_url
.unwrap_or("https://api.openshock.app".to_string());
let Some(default_key) = self.default_key else {
return Err(Error::MissingApiToken);
};

impl OpenShockAPI {
/// Create a new instance of the api interface with a default key and the base_url, because OpenShock can be self hosted `base_url` can be any url without the leading `/` if `None` is provided the default of <https://api.shocklink.net> is used.
pub fn new(base_url: Option<String>, default_key: String) -> Self {
let mut headers = header::HeaderMap::new();
headers.insert(
"Content-type",
Expand All @@ -33,12 +55,44 @@ impl OpenShockAPI {
.default_headers(headers)
.build()
.unwrap();
let base_url = base_url.unwrap_or("https://api.openshock.app".to_string());
OpenShockAPI {

Ok(OpenShockAPI {
client,
base_url,
default_key,
})
}
}

/// All methods contain an `Option<String>` to provide an alternate api key to use if it differs from the default
pub struct OpenShockAPI {
client: reqwest::Client,
base_url: String,
default_key: String,
}

/// Which list of shockers to return
#[derive(EnumString, Debug)]
pub enum ListShockerSource {
Own,
Shared,
}

impl OpenShockAPI {
/// Return a builder for the api interface
///
/// this is the same as [`OpenShockAPIBuilder::new`]
pub fn builder() -> OpenShockAPIBuilder {
OpenShockAPIBuilder::new()
}

/// Create a new instance of the api interface with a default key and the base_url, because OpenShock can be self hosted `base_url` can be any url without the leading `/` if `None` is provided the default of <https://api.shocklink.net> is used.
pub fn new(base_url: Option<String>, default_key: String) -> Self {
let mut builder = Self::builder().with_default_api_token(default_key);
if let Some(base_url) = base_url {
builder = builder.with_base_url(base_url);
}
builder.build().unwrap()
}

/// Gets user info from the provided API key, the default key from the instance is used if `None` is provided
Expand Down
6 changes: 6 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
/// Error type for functions in this crate
#[derive(Debug)]
pub enum Error {
/// error propagated from reqwest
Reqwest(reqwest::Error),
/// error propagated from serde
Serde(serde_json::Error),
/// no API token was provided to the API interface
MissingApiToken,
}

impl From<reqwest::Error> for Error {
Expand All @@ -22,6 +26,7 @@ impl std::fmt::Display for Error {
match self {
Self::Reqwest(e) => e.fmt(f),
Self::Serde(e) => e.fmt(f),
Self::MissingApiToken => write!(f, "no API token was provided"),
}
}
}
Expand All @@ -31,6 +36,7 @@ impl std::error::Error for Error {
match self {
Self::Reqwest(e) => e.source(),
Self::Serde(e) => e.source(),
Self::MissingApiToken => None,
}
}
}

0 comments on commit b489067

Please sign in to comment.