maverick_os 0.1.3

Maverick OS
use std::sync::Arc;
use std::path::PathBuf;
use std::fmt::Debug;

use serde::{Serialize, Deserialize};

#[cfg(target_os = "android")]
use winit_crate::platform::android::activity::AndroidApp;

#[cfg(not(target_arch = "wasm32"))]
use tokio::sync::Mutex;

#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug, Clone)]
pub struct Cache(
    Arc<Mutex<rusqlite::Connection>>
);

#[cfg(not(target_arch = "wasm32"))]
impl Cache {
    pub(crate) fn new() -> Self {
        let storage_path = PathBuf::from("./");
        std::fs::create_dir_all(&storage_path).unwrap();
        let path = storage_path.join("cache.db");
        let db = rusqlite::Connection::open(path).unwrap();
        db.execute(
            "CREATE TABLE if not exists kvs(key TEXT NOT NULL UNIQUE, value TEXT);", []
        ).unwrap();
        Cache(Arc::new(Mutex::new(db)))
    }

    pub async fn set<
        K: Serialize + for<'a> Deserialize <'a>,
        V: Serialize + for<'a> Deserialize <'a> + Default,
    >(&self, key: K, value: V) {
        self.0.lock().await.execute(
            "INSERT INTO kvs(key, value) VALUES (?1, ?2) ON CONFLICT(key) DO UPDATE SET value=excluded.value;",
            [hex::encode(serde_json::to_vec(&key).unwrap()), hex::encode(serde_json::to_vec(&value).unwrap())]
        ).unwrap();
    }
    pub async fn get<
        K: Serialize + for<'a> Deserialize <'a>,
        V: Serialize + for<'a> Deserialize <'a> + Default,
    >(&self, key: &K) -> V {
        let db = self.0.lock().await;
        let mut stmt = db.prepare(
            &format!("SELECT value FROM kvs where key = \'{}\'", hex::encode(serde_json::to_vec(&key).unwrap())),
        ).unwrap();
        let result = stmt.query_and_then([], |row| {
            let item: String = row.get(0).unwrap();
            Ok(hex::decode(item).unwrap())
        }).unwrap().collect::<Result<Vec<Vec<u8>>, rusqlite::Error>>().unwrap();
        result.first().and_then(|b| serde_json::from_slice(b).ok()).unwrap_or_default()
    }
}