use azure_storage::StorageCredentials;
use azure_storage_blobs::prelude::{ClientBuilder, ContainerClient};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StorageConfig {
#[cfg_attr(feature = "serde", serde(default))]
pub credentials: Credential,
pub location: CloudLocation,
pub container: String,
}
impl StorageConfig {
pub(crate) fn dummy() -> Self {
StorageConfig {
credentials: Credential::Anonymous,
container: "dummy-test".into(),
location: CloudLocation::Public("dummy".into()),
}
}
}
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Credential {
AccessKey { account: String, access_key: String },
SASToken(String),
Bearer(String),
#[default]
Anonymous,
}
impl TryFrom<Credential> for StorageCredentials {
type Error = azure_storage::Error;
fn try_from(value: Credential) -> Result<Self, Self::Error> {
match value {
Credential::AccessKey { account, access_key } => Ok(StorageCredentials::access_key(account, access_key)),
Credential::SASToken(token) => StorageCredentials::sas_token(token),
Credential::Bearer(token) => Ok(StorageCredentials::bearer_token(token)),
Credential::Anonymous => Ok(StorageCredentials::anonymous()),
}
}
}
impl TryFrom<StorageConfig> for ContainerClient {
type Error = azure_storage::Error;
fn try_from(value: StorageConfig) -> Result<Self, Self::Error> {
Ok(
ClientBuilder::with_location::<StorageCredentials>(value.location.into(), value.credentials.try_into()?)
.container_client(value.container),
)
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum CloudLocation {
Public(String),
China(String),
Emulator {
address: String,
port: u16,
},
Custom {
account: String,
uri: String,
},
}
impl From<CloudLocation> for azure_storage::CloudLocation {
fn from(value: CloudLocation) -> Self {
match value {
CloudLocation::Public(account) => azure_storage::CloudLocation::Public { account },
CloudLocation::China(account) => azure_storage::CloudLocation::China { account },
CloudLocation::Emulator { address, port } => azure_storage::CloudLocation::Emulator { address, port },
CloudLocation::Custom { account, uri } => azure_storage::CloudLocation::Custom { account, uri },
}
}
}