use super::Memory;
use crate::embedding::EmbeddingProvider;
use crate::llm::LLMProvider;
use crate::storage::{StorageBackend, VectorBackend};
pub struct MemoryBuilder<L, E, V, S> {
llm: Option<L>,
embedder: Option<E>,
vector: Option<V>,
storage: Option<S>,
}
impl<L, E, V, S> MemoryBuilder<L, E, V, S>
where
L: LLMProvider + Clone,
E: EmbeddingProvider + Clone,
V: VectorBackend + Clone,
S: StorageBackend + Clone,
{
#[must_use]
pub fn new() -> Self {
Self {
llm: None,
embedder: None,
vector: None,
storage: None,
}
}
#[must_use]
pub fn with_llm(mut self, llm: L) -> Self {
self.llm = Some(llm);
self
}
#[must_use]
pub fn with_embedder(mut self, embedder: E) -> Self {
self.embedder = Some(embedder);
self
}
#[must_use]
pub fn with_vector(mut self, vector: V) -> Self {
self.vector = Some(vector);
self
}
#[must_use]
pub fn with_storage(mut self, storage: S) -> Self {
self.storage = Some(storage);
self
}
#[must_use]
pub fn build(self) -> Memory<L, E, S, V> {
let llm = self.llm.expect("LLM provider is required");
let embedder = self.embedder.expect("Embedder is required");
let vector = self.vector.expect("Vector backend is required");
let storage = self.storage.expect("Storage backend is required");
Memory::new(llm, embedder, vector, storage)
}
}
impl<L, E, V, S> Default for MemoryBuilder<L, E, V, S>
where
L: LLMProvider + Clone,
E: EmbeddingProvider + Clone,
V: VectorBackend + Clone,
S: StorageBackend + Clone,
{
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::dst::SimConfig;
use crate::embedding::SimEmbeddingProvider;
use crate::llm::SimLLMProvider;
use crate::storage::{SimStorageBackend, SimVectorBackend};
#[test]
fn test_builder_construction() {
let builder = MemoryBuilder::<
SimLLMProvider,
SimEmbeddingProvider,
SimVectorBackend,
SimStorageBackend,
>::new();
assert!(builder.llm.is_none());
assert!(builder.embedder.is_none());
assert!(builder.vector.is_none());
assert!(builder.storage.is_none());
}
#[test]
fn test_builder_with_methods() {
let llm = SimLLMProvider::with_seed(42);
let embedder = SimEmbeddingProvider::with_seed(42);
let vector = SimVectorBackend::new(42);
let storage = SimStorageBackend::new(SimConfig::with_seed(42));
let builder = MemoryBuilder::new()
.with_llm(llm)
.with_embedder(embedder)
.with_vector(vector)
.with_storage(storage);
assert!(builder.llm.is_some());
assert!(builder.embedder.is_some());
assert!(builder.vector.is_some());
assert!(builder.storage.is_some());
}
#[test]
#[should_panic(expected = "LLM provider is required")]
fn test_builder_missing_llm() {
use crate::umi::Memory;
let _memory: Memory<SimLLMProvider, SimEmbeddingProvider, SimStorageBackend, SimVectorBackend> =
MemoryBuilder::new()
.with_embedder(SimEmbeddingProvider::with_seed(42))
.with_vector(SimVectorBackend::new(42))
.with_storage(SimStorageBackend::new(SimConfig::with_seed(42)))
.build();
}
#[test]
#[should_panic(expected = "Embedder is required")]
fn test_builder_missing_embedder() {
use crate::umi::Memory;
let _memory: Memory<SimLLMProvider, SimEmbeddingProvider, SimStorageBackend, SimVectorBackend> =
MemoryBuilder::new()
.with_llm(SimLLMProvider::with_seed(42))
.with_vector(SimVectorBackend::new(42))
.with_storage(SimStorageBackend::new(SimConfig::with_seed(42)))
.build();
}
}