use std::path::PathBuf;
use kiromi_ai_memory::{InMemoryBackend, LocalFsBackend, MetadataStore, SqliteMetadata, Storage};
use crate::error::{CliError, ExitCode};
pub(crate) async fn parse_storage(uri: &str) -> Result<Box<dyn Storage>, CliError> {
if let Some(rest) = uri.strip_prefix("local:") {
let p = PathBuf::from(rest);
let s = LocalFsBackend::new(p).await.map_err(CliError::from)?;
return Ok(Box::new(s));
}
if uri == "memory:" || uri == "memory" {
return Ok(Box::new(InMemoryBackend::new()));
}
Err(CliError {
kind: ExitCode::Config,
source: anyhow::anyhow!("unrecognised storage URI {uri:?}"),
})
}
pub(crate) async fn parse_metadata(uri: &str) -> Result<Box<dyn MetadataStore>, CliError> {
if uri == "sqlite::memory:" {
let m = SqliteMetadata::connect_memory()
.await
.map_err(CliError::from)?;
return Ok(Box::new(m));
}
if let Some(rest) = uri.strip_prefix("sqlite:") {
let m = SqliteMetadata::connect_file(rest)
.await
.map_err(CliError::from)?;
return Ok(Box::new(m));
}
Err(CliError {
kind: ExitCode::Config,
source: anyhow::anyhow!("unrecognised metadata URI {uri:?}"),
})
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn parses_memory_storage() {
let s = parse_storage("memory:").await.unwrap();
assert!(!s.id().is_empty());
}
#[tokio::test]
async fn parses_sqlite_in_memory() {
let m = parse_metadata("sqlite::memory:").await.unwrap();
assert!(!m.id().is_empty());
}
#[tokio::test]
async fn rejects_unknown_storage_scheme() {
let err = parse_storage("s3://bucket/key").await.unwrap_err();
assert_eq!(err.kind, ExitCode::Config);
}
#[tokio::test]
async fn rejects_unknown_metadata_scheme() {
let err = parse_metadata("postgres://x").await.unwrap_err();
assert_eq!(err.kind, ExitCode::Config);
}
}