Skip to content

Commit

Permalink
Implement update key (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonxslays committed Aug 26, 2023
1 parent 67b1542 commit 433e8e0
Show file tree
Hide file tree
Showing 7 changed files with 416 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
- Add `create_key` method.
- Add `verify_key` method.
- Add `revoke_key` method.
- Add `update_key` method.
- Add `list_keys` method.
- Add `get_api` method.
- Add various models supporting api service.
- Add various models supporting key service.
- Add `get_api` method.
28 changes: 28 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::models::GetApiResponse;
use crate::models::ListKeysRequest;
use crate::models::ListKeysResponse;
use crate::models::RevokeKeyRequest;
use crate::models::UpdateKeyRequest;
use crate::models::VerifyKeyRequest;
use crate::models::VerifyKeyResponse;
use crate::models::Wrapped;
Expand Down Expand Up @@ -240,4 +241,31 @@ impl Client {
pub async fn get_api(&self, req: GetApiRequest) -> Wrapped<GetApiResponse> {
self.apis.get_api(&self.http, req).await
}

/// Retrieves information for the given api id.
///
/// # Arguments
/// - `req`: The get api request to send.
///
/// # Returns
/// A wrapper containing the response, or an [`HttpError`].
///
/// # Example
/// ```no_run
/// # async fn get() {
/// # use unkey::Client;
/// # use unkey::models::UpdateKeyRequest;
/// # use unkey::models::Wrapped;
/// let c = Client::new("abc123");
/// let req = UpdateKeyRequest::new("api_id").set_remaining(Some(100));
///
/// match c.update_key(req).await {
/// Wrapped::Ok(res) => println!("{:?}", res),
/// Wrapped::Err(err) => println!("{:?}", err),
/// }
/// # }
/// ````
pub async fn update_key(&self, req: UpdateKeyRequest) -> Wrapped<()> {
self.keys.update_key(&self.http, req).await
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]

mod client;
mod logging;
pub mod models;
mod routes;
mod services;
pub mod undefined;

use serde::Deserialize;

Expand Down Expand Up @@ -96,6 +99,7 @@ pub(crate) async fn wrap_empty_response(result: HttpResult) -> Wrapped<()> {
}
}

/// Fetchs the given route with the provided http service.
macro_rules! fetch {
($http:expr, $route:ident) => {
$http.fetch($route, None::<u8>)
Expand Down
295 changes: 295 additions & 0 deletions src/models/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde_json::Value;

use super::Ratelimit;
use super::RatelimitState;
use crate::undefined::UndefinedOr;

/// An outgoing verify key request.
#[derive(Debug, Clone, Serialize)]
Expand Down Expand Up @@ -407,3 +408,297 @@ impl RevokeKeyRequest {
Self { key_id: key_id.into() }
}
}

/// An outgoing update key request.
///
/// ## Note
/// All optional values are initialized to the [`UndefinedOr::Undefined`] state.
/// Upon calling the `set_x` method, you may set the value to `Some(_)` or
/// `None`. Setting the value to `None` indicates you would like to remove any
/// value that is currently set for that field on the key.
///
/// e.g. The key you are updating currently has a ratelimit and you call
/// `set_ratelimit(None)` on the update key request. The key will no longer
/// have a ratelimit.
#[derive(Debug, Default, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UpdateKeyRequest {
/// The id of the key to update.
pub key_id: String,

/// The optional new owner id for the key.
#[serde(skip_serializing_if = "UndefinedOr::is_undefined")]
pub owner_id: UndefinedOr<Option<String>>,

/// The optional new name for the key.
#[serde(skip_serializing_if = "UndefinedOr::is_undefined")]
pub name: UndefinedOr<Option<String>>,

/// The optional new dynamic meta mapping for the key.
#[serde(skip_serializing_if = "UndefinedOr::is_undefined")]
pub meta: UndefinedOr<Option<Value>>,

/// The optional new unix epoch in ms when the key should expire.
#[serde(skip_serializing_if = "UndefinedOr::is_undefined")]
pub expires: UndefinedOr<Option<usize>>,

/// The optional new number of uses remaining to set for the key.
#[serde(skip_serializing_if = "UndefinedOr::is_undefined")]
pub remaining: UndefinedOr<Option<usize>>,

/// The optional new ratelimit to set for the key.
#[serde(skip_serializing_if = "UndefinedOr::is_undefined")]
pub ratelimit: UndefinedOr<Option<Ratelimit>>,
}

impl UpdateKeyRequest {
/// Creates a new update key request.
///
/// # Arguments
/// - `key_id`: The id of the key to update.
///
/// # Returns
/// The new update key request.
///
/// # Example
/// ```
/// # use unkey::models::UpdateKeyRequest;
/// # use unkey::undefined::UndefinedOr;
/// let r = UpdateKeyRequest::new("test_123");
///
/// assert_eq!(r.key_id, String::from("test_123"));
/// assert_eq!(r.owner_id, UndefinedOr::Undefined);
/// assert_eq!(r.name, UndefinedOr::Undefined);
/// assert_eq!(r.meta, UndefinedOr::Undefined);
/// assert_eq!(r.expires, UndefinedOr::Undefined);
/// assert_eq!(r.remaining, UndefinedOr::Undefined);
/// assert_eq!(r.ratelimit, UndefinedOr::Undefined);
/// ```
#[must_use]
pub fn new<T: Into<String>>(key_id: T) -> Self {
Self {
key_id: key_id.into(),
..Default::default()
}
}

/// Sets or unsets the owner id for the key.
///
/// # Arguments
/// - `owner_id`: The owner id to set or unset.
///
/// # Returns
/// Self for chained calls.
///
/// # Example
/// ```
/// # use unkey::models::UpdateKeyRequest;
/// # use unkey::undefined::UndefinedOr;
/// let r = UpdateKeyRequest::new("test");
///
/// assert_eq!(r.owner_id, UndefinedOr::Undefined);
/// assert_eq!(*r.owner_id, None);
///
/// let r = r.set_owner_id(Some("jonxslays"));
///
/// assert_eq!(r.owner_id, UndefinedOr::Value(Some(String::from("jonxslays"))));
/// assert_eq!(*r.owner_id, Some(String::from("jonxslays")));
///
/// let r = r.set_owner_id(None);
///
/// assert_eq!(r.owner_id, UndefinedOr::Null);
/// assert_eq!(*r.owner_id, None);
/// ```
#[must_use]
pub fn set_owner_id(mut self, owner_id: Option<&str>) -> Self {
self.owner_id = match owner_id {
Some(id) => Some(id.into()).into(),
None => None.into(),
};

self
}

/// Sets or unsets the name for the key.
///
/// # Arguments
/// - `name`: The name to set or unset.
///
/// # Returns
/// Self for chained calls.
///
/// # Example
/// ```
/// # use unkey::models::UpdateKeyRequest;
/// # use unkey::undefined::UndefinedOr;
/// let r = UpdateKeyRequest::new("test");
///
/// assert_eq!(r.name, UndefinedOr::Undefined);
/// assert_eq!(*r.name, None);
///
/// let r = r.set_name(Some("test_key"));
///
/// assert_eq!(r.name, UndefinedOr::Value(Some(String::from("test_key"))));
/// assert_eq!(*r.name, Some(String::from("test_key")));
///
/// let r = r.set_name(None);
///
/// assert_eq!(r.name, UndefinedOr::Null);
/// assert_eq!(*r.name, None);
/// ```
#[must_use]
pub fn set_name(mut self, name: Option<&str>) -> Self {
self.name = match name {
Some(n) => Some(n.into()).into(),
None => None.into(),
};

self
}

/// Sets or unsets the dynamic meta mapping for the key.
///
/// # Arguments
/// - `meta`: The meta to set or unset.
///
/// # Returns
/// Self for chained calls.
///
/// # Example
/// ```
/// # use unkey::models::UpdateKeyRequest;
/// # use unkey::undefined::UndefinedOr;
/// # use serde_json::json;
/// let r = UpdateKeyRequest::new("test");
///
/// assert_eq!(r.meta, UndefinedOr::Undefined);
/// assert_eq!(*r.meta, None);
///
/// let r = r.set_meta(Some(json!({"test": 69})));
///
/// assert_eq!(r.meta, UndefinedOr::Value(Some(json!({"test": 69}))));
/// assert_eq!(*r.meta, Some(json!({"test": 69})));
///
/// let r = r.set_meta(None);
///
/// assert_eq!(r.meta, UndefinedOr::Null);
/// assert_eq!(*r.meta, None);
/// ```
#[must_use]
pub fn set_meta(mut self, meta: Option<Value>) -> Self {
self.meta = match meta {
Some(m) => Some(m).into(),
None => None.into(),
};

self
}

/// Sets or unsets the unix epoch in ms indicating when this key expires.
///
/// # Arguments
/// - `expires`: The expiration epoch to set or unset.
///
/// # Returns
/// Self for chained calls.
///
/// # Example
/// ```
/// # use unkey::models::UpdateKeyRequest;
/// # use unkey::undefined::UndefinedOr;
/// let r = UpdateKeyRequest::new("test");
///
/// assert_eq!(r.expires, UndefinedOr::Undefined);
/// assert_eq!(*r.expires, None);
///
/// let r = r.set_expires(Some(42));
///
/// assert_eq!(r.expires, UndefinedOr::Value(Some(42)));
/// assert_eq!(*r.expires, Some(42));
///
/// let r = r.set_expires(None);
///
/// assert_eq!(r.expires, UndefinedOr::Null);
/// assert_eq!(*r.expires, None);
/// ```
#[must_use]
pub fn set_expires(mut self, expires: Option<usize>) -> Self {
self.expires = expires.into();
self
}

/// Sets or unsets the remaining uses for the key.
///
/// # Arguments
/// - `remaining`: The number of remaining uses to set or unset.
///
/// # Returns
/// Self for chained calls.
///
/// # Example
/// ```
/// # use unkey::models::UpdateKeyRequest;
/// # use unkey::undefined::UndefinedOr;
/// let r = UpdateKeyRequest::new("test");
///
/// assert_eq!(r.remaining, UndefinedOr::Undefined);
/// assert_eq!(*r.remaining, None);
///
/// let r = r.set_remaining(Some(420));
///
/// assert_eq!(r.remaining, UndefinedOr::Value(Some(420)));
/// assert_eq!(*r.remaining, Some(420));
///
/// let r = r.set_remaining(None);
///
/// assert_eq!(r.remaining, UndefinedOr::Null);
/// assert_eq!(*r.remaining, None);
/// ```
#[must_use]
pub fn set_remaining(mut self, remaining: Option<usize>) -> Self {
self.remaining = remaining.into();
self
}

/// Sets or unsets the ratelimit for the key.
///
/// # Arguments
/// - `ratelimit`: The ratelimit to set or unset.
///
/// # Returns
/// Self for chained calls.
///
/// # Example
/// ```
/// # use unkey::models::UpdateKeyRequest;
/// # use unkey::models::Ratelimit;
/// # use unkey::models::RatelimitType;
/// # use unkey::undefined::UndefinedOr;
/// let r = UpdateKeyRequest::new("test");
///
/// assert_eq!(r.ratelimit, UndefinedOr::Undefined);
/// assert_eq!(*r.ratelimit, None);
///
/// let ratelimit = Ratelimit::new(
/// RatelimitType::Fast,
/// 10,
/// 10000,
/// 100
/// );
///
/// let r = r.set_ratelimit(Some(ratelimit.clone()));
///
/// assert_eq!(r.ratelimit, UndefinedOr::Value(Some(ratelimit.clone())));
/// assert_eq!(*r.ratelimit, Some(ratelimit));
///
/// let r = r.set_ratelimit(None);
///
/// assert_eq!(r.ratelimit, UndefinedOr::Null);
/// assert_eq!(*r.ratelimit, None);
/// ```
#[must_use]
pub fn set_ratelimit(mut self, ratelimit: Option<Ratelimit>) -> Self {
self.ratelimit = ratelimit.into();
self
}
}
1 change: 0 additions & 1 deletion src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub(crate) static VERIFY_KEY: Route = Route::new(Method::POST, "/keys/verify");
pub(crate) static REVOKE_KEY: Route = Route::new(Method::DELETE, "/keys/{}");

/// The update key endpoint `PUT /keys/{id}`
#[allow(unused)] // Temporary until we implement this method
pub(crate) static UPDATE_KEY: Route = Route::new(Method::PUT, "/keys/{}");

////////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit 433e8e0

Please sign in to comment.