use anyhow::Result;
use async_trait::async_trait;
use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json::Value;
#[async_trait]
pub trait MemoryStorage: Send + Sync {
async fn save_json_value(&self, category: &str, key: &str, value: &Value) -> Result<()>;
async fn load_json_value(&self, category: &str, key: &str) -> Result<Option<Value>>;
async fn list_category(&self, category: &str) -> Result<Vec<String>>;
async fn delete_file(&self, category: &str, key: &str) -> Result<bool>;
}
#[async_trait]
pub trait MemoryStorageExt: MemoryStorage {
async fn save_json<T: Serialize + Send + Sync>(
&self,
category: &str,
key: &str,
value: &T,
) -> Result<()> {
let v = serde_json::to_value(value)?;
self.save_json_value(category, key, &v).await
}
async fn load_json<T: DeserializeOwned + Send>(
&self,
category: &str,
key: &str,
) -> Result<Option<T>> {
match self.load_json_value(category, key).await? {
Some(v) => Ok(Some(serde_json::from_value(v)?)),
None => Ok(None),
}
}
}
impl<S: MemoryStorage + ?Sized> MemoryStorageExt for S {}
#[async_trait]
pub trait MemoryGit: Send + Sync {
async fn commit_file(&self, path: &str, message: &str) -> Result<()>;
fn is_enabled(&self) -> bool;
}
#[derive(Debug, Clone)]
pub struct NoteEntry {
pub name: String,
pub parent_dir: String,
pub is_dir: bool,
}
pub trait MarkdownSource: Send + Sync {
fn index_all(&self) -> Result<usize>;
fn note_tree(&self, dir: &str) -> Result<Vec<NoteEntry>>;
fn note_read(&self, path: &str) -> Result<Option<String>>;
fn extract_headings(&self, content: &str) -> Vec<String>;
}