mod file;
mod memory;
use crate::{Result, Token};
use async_trait::async_trait;
use std::{path::PathBuf, sync::Arc, time::Duration};
pub use file::FileStore;
pub use memory::MemoryStore;
#[async_trait]
pub trait StorageLock: Send + Sync {
async fn release(self: Box<Self>) -> Result<()> {
Ok(())
}
}
#[async_trait]
pub trait CredentialStore: Send + Sync {
async fn load(&self, key: &str) -> Result<Option<Token>>;
async fn prepare_write(&self) -> Result<()> {
Ok(())
}
async fn save(&self, key: &str, token: &Token) -> Result<()>;
async fn delete(&self, key: &str) -> Result<()>;
async fn lock(&self, key: &str, timeout: Duration) -> Result<Box<dyn StorageLock>>;
fn name(&self) -> &'static str;
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, uniffi::Enum)]
pub enum Storage {
#[default]
Auto,
Memory,
File,
}
pub type StoreBackend = Storage;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, uniffi::Enum)]
pub enum FileLayout {
#[default]
Single,
PerCredential,
}
pub async fn open_store(
backend: Storage,
directory: PathBuf,
layout: FileLayout,
) -> Result<Arc<dyn CredentialStore>> {
match backend {
Storage::Memory => Ok(Arc::new(MemoryStore::new())),
Storage::Auto | Storage::File => Ok(Arc::new(FileStore::with_layout(directory, layout)?)),
}
}