use std::fmt;
use serde::{Deserialize, Serialize};
use crate::api_key::ApiKeyError;
#[derive(
Debug,
Serialize,
Deserialize,
Clone,
Eq,
PartialEq,
Default,
strum::EnumIter,
)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ApiKeyRoleScope {
ManageApiKeys,
HistoricalData,
#[default]
LiveData,
RestApi,
}
impl ApiKeyRoleScope {
pub fn as_str(&self) -> &str {
match self {
ApiKeyRoleScope::ManageApiKeys => "MANAGE_API_KEYS",
ApiKeyRoleScope::HistoricalData => "HISTORICAL_DATA",
ApiKeyRoleScope::LiveData => "LIVE_DATA",
ApiKeyRoleScope::RestApi => "REST_API",
}
}
pub fn is_manage_api_keys(&self) -> bool {
matches!(self, ApiKeyRoleScope::ManageApiKeys)
}
pub fn is_historical_data(&self) -> bool {
matches!(self, ApiKeyRoleScope::HistoricalData)
}
pub fn is_live_data(&self) -> bool {
matches!(self, ApiKeyRoleScope::LiveData)
}
pub fn is_rest_api(&self) -> bool {
matches!(self, ApiKeyRoleScope::RestApi)
}
}
impl fmt::Display for ApiKeyRoleScope {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl TryFrom<&str> for ApiKeyRoleScope {
type Error = ApiKeyError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"MANAGE_API_KEYS" => Ok(ApiKeyRoleScope::ManageApiKeys),
"HISTORICAL_DATA" => Ok(ApiKeyRoleScope::HistoricalData),
"LIVE_DATA" => Ok(ApiKeyRoleScope::LiveData),
"REST_API" => Ok(ApiKeyRoleScope::RestApi),
_ => Err(ApiKeyError::ScopePermission(value.to_string())),
}
}
}
impl sqlx::Type<sqlx::Postgres> for ApiKeyRoleScope {
fn type_info() -> sqlx::postgres::PgTypeInfo {
sqlx::postgres::PgTypeInfo::with_name("api_scope")
}
}
impl<'r> sqlx::Decode<'r, sqlx::Postgres> for ApiKeyRoleScope {
fn decode(
value: sqlx::postgres::PgValueRef<'r>,
) -> Result<Self, sqlx::error::BoxDynError> {
let value = <&str as sqlx::Decode<sqlx::Postgres>>::decode(value)?;
ApiKeyRoleScope::try_from(value).map_err(|e| e.to_string().into())
}
}
impl sqlx::Encode<'_, sqlx::Postgres> for ApiKeyRoleScope {
fn encode_by_ref(
&self,
buf: &mut sqlx::postgres::PgArgumentBuffer,
) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
<&str as sqlx::Encode<sqlx::Postgres>>::encode_by_ref(
&self.as_str(),
buf,
)
}
}
impl sqlx::postgres::PgHasArrayType for ApiKeyRoleScope {
fn array_type_info() -> sqlx::postgres::PgTypeInfo {
sqlx::postgres::PgTypeInfo::with_name("_api_scope")
}
}