bone-persistence 0.1.0

Persistence layer for BoneTools
Documentation
use crate::error::Result;
use crate::persistence::Persistence;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::sync::Arc;

/// 后端类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BackendType {
    Sqlite,
}

/// 持久化配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PersistenceConfig {
    pub backend_type: BackendType,
    pub location: PathBuf,
    pub id: String,
}

impl Default for PersistenceConfig {
    fn default() -> Self {
        let data_dir = dirs::data_dir().unwrap();

        Self {
            backend_type: BackendType::Sqlite,
            location: data_dir.join("bone-persistence"),
            id: "default".to_string(),
        }
    }
}

pub struct PersistFactory;

impl PersistFactory {
    pub async fn create<ValueT, MetaDataT>(
        config: PersistenceConfig,
    ) -> Result<Arc<dyn Persistence<ValueT, MetaDataT>>>
    where
        ValueT: Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static,
        MetaDataT: Clone + Default + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static,
    {
        use crate::backends::sqlite::SqliteBackend;
        match config.backend_type {
            BackendType::Sqlite => {
                let db_path = config.location.join(format!("{}.db", config.id));
                let backend = SqliteBackend::new(&db_path).await?;
                <SqliteBackend as Persistence<ValueT, MetaDataT>>::init(&backend).await?;
                Ok(Arc::new(backend))
            }
        }
    }

    pub async fn create_default<ValueT, MetaDataT>()
    -> Result<Arc<dyn Persistence<ValueT, MetaDataT>>>
    where
        ValueT: Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static,
        MetaDataT: Clone + Default + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static,
    {
        Self::create(PersistenceConfig::default()).await
    }
}