use async_trait::async_trait;
use everruns_core::{WorkspaceRootSet, session_files::SessionFileSystem};
use everruns_provider::error::{AgentLoopError, Result};
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Clone, Default)]
pub struct SessionFileSystemFactoryContext {
values: Arc<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>,
}
impl SessionFileSystemFactoryContext {
pub fn new() -> Self {
Self::default()
}
pub fn with<T: Any + Send + Sync>(mut self, value: Arc<T>) -> Self {
let values = Arc::make_mut(&mut self.values);
values.insert(TypeId::of::<T>(), value);
self
}
pub fn get<T: Any + Send + Sync>(&self) -> Option<Arc<T>> {
self.values
.get(&TypeId::of::<T>())
.and_then(|value| value.clone().downcast::<T>().ok())
}
pub fn with_workspace_roots(self, roots: Arc<WorkspaceRootSet>) -> Self {
self.with(roots)
}
pub fn workspace_roots(&self) -> Option<Arc<WorkspaceRootSet>> {
self.get::<WorkspaceRootSet>()
}
}
#[async_trait]
pub trait SessionFileSystemFactory: Send + Sync {
fn name(&self) -> &'static str {
"SessionFileSystemFactory"
}
fn is_disabled(&self) -> bool {
false
}
async fn create_session_file_system(
&self,
context: SessionFileSystemFactoryContext,
) -> Result<Arc<dyn SessionFileSystem>>;
}
#[derive(Debug, Clone, Default)]
pub struct DisabledSessionFileSystemFactory;
#[async_trait]
impl SessionFileSystemFactory for DisabledSessionFileSystemFactory {
fn name(&self) -> &'static str {
"DisabledSessionFileSystemFactory"
}
fn is_disabled(&self) -> bool {
true
}
async fn create_session_file_system(
&self,
_context: SessionFileSystemFactoryContext,
) -> Result<Arc<dyn SessionFileSystem>> {
Err(AgentLoopError::config("session filesystem is disabled"))
}
}
#[derive(Clone)]
pub struct FixedSessionFileSystemFactory {
file_system: Arc<dyn SessionFileSystem>,
}
impl FixedSessionFileSystemFactory {
pub fn new(file_system: Arc<dyn SessionFileSystem>) -> Self {
Self { file_system }
}
}
#[async_trait]
impl SessionFileSystemFactory for FixedSessionFileSystemFactory {
fn name(&self) -> &'static str {
"FixedSessionFileSystemFactory"
}
async fn create_session_file_system(
&self,
_context: SessionFileSystemFactoryContext,
) -> Result<Arc<dyn SessionFileSystem>> {
Ok(self.file_system.clone())
}
}