use std::{collections::BTreeMap, sync::Arc};
use async_trait::async_trait;
pub use loong_contracts::{
MemoryCoreOutcome, MemoryCoreRequest, MemoryExtensionOutcome, MemoryExtensionRequest,
MemoryTier,
};
use crate::errors::MemoryPlaneError;
#[async_trait]
pub trait CoreMemoryAdapter: Send + Sync {
fn name(&self) -> &str;
async fn execute_core_memory(
&self,
request: MemoryCoreRequest,
) -> Result<MemoryCoreOutcome, MemoryPlaneError>;
}
#[async_trait]
pub trait MemoryExtensionAdapter: Send + Sync {
fn name(&self) -> &str;
async fn execute_memory_extension(
&self,
request: MemoryExtensionRequest,
core: &(dyn CoreMemoryAdapter + Sync),
) -> Result<MemoryExtensionOutcome, MemoryPlaneError>;
}
#[derive(Default)]
pub struct MemoryPlane {
core_adapters: BTreeMap<String, Arc<dyn CoreMemoryAdapter>>,
extension_adapters: BTreeMap<String, Arc<dyn MemoryExtensionAdapter>>,
default_core_adapter: Option<String>,
}
impl MemoryPlane {
#[must_use]
pub fn new() -> Self {
Self {
core_adapters: BTreeMap::new(),
extension_adapters: BTreeMap::new(),
default_core_adapter: None,
}
}
pub fn register_core_adapter<A: CoreMemoryAdapter + 'static>(&mut self, adapter: A) {
let name = adapter.name().to_owned();
if self.default_core_adapter.is_none() {
self.default_core_adapter = Some(name.clone());
}
self.core_adapters.insert(name, Arc::new(adapter));
}
pub fn register_extension_adapter<A: MemoryExtensionAdapter + 'static>(&mut self, adapter: A) {
let name = adapter.name().to_owned();
self.extension_adapters.insert(name, Arc::new(adapter));
}
pub fn set_default_core_adapter(&mut self, name: &str) -> Result<(), MemoryPlaneError> {
if !self.core_adapters.contains_key(name) {
return Err(MemoryPlaneError::CoreAdapterNotFound(name.to_owned()));
}
self.default_core_adapter = Some(name.to_owned());
Ok(())
}
#[must_use]
pub fn default_core_adapter_name(&self) -> Option<&str> {
self.default_core_adapter.as_deref()
}
pub async fn execute_core(
&self,
core_name: Option<&str>,
request: MemoryCoreRequest,
) -> Result<MemoryCoreOutcome, MemoryPlaneError> {
let resolved_name = if let Some(name) = core_name {
name
} else {
self.default_core_adapter
.as_deref()
.ok_or(MemoryPlaneError::NoDefaultCoreAdapter)?
};
let adapter = self
.core_adapters
.get(resolved_name)
.ok_or(MemoryPlaneError::CoreAdapterNotFound(
resolved_name.to_owned(),
))?
.clone();
return adapter.execute_core_memory(request).await;
}
pub async fn execute_extension(
&self,
extension_name: &str,
core_name: Option<&str>,
request: MemoryExtensionRequest,
) -> Result<MemoryExtensionOutcome, MemoryPlaneError> {
let extension = self
.extension_adapters
.get(extension_name)
.ok_or_else(|| MemoryPlaneError::ExtensionNotFound(extension_name.to_owned()))?
.clone();
let resolved_core_name = if let Some(name) = core_name {
name
} else {
self.default_core_adapter
.as_deref()
.ok_or(MemoryPlaneError::NoDefaultCoreAdapter)?
};
let core = self
.core_adapters
.get(resolved_core_name)
.ok_or(MemoryPlaneError::CoreAdapterNotFound(
resolved_core_name.to_owned(),
))?
.clone();
return extension
.execute_memory_extension(request, core.as_ref())
.await;
}
}