use std::path::{Path, PathBuf};
use std::sync::Arc;
use bevy_ecs::prelude::*;
use rig_core::tool::content_hash;
use rig_harness_protocol::{Home, SessionDir};
use rig_memory::{DirFiles, Files, MemoryStore, PluginFiles, SessionError};
use crate::host::session::StoreOpener;
#[derive(Resource, Clone)]
pub struct PluginData {
pub session: Arc<dyn Files>,
pub project: Arc<dyn Files>,
pub user: Arc<dyn Files>,
}
impl PluginData {
pub(crate) fn new(
home: &Home,
session: Option<Arc<dyn Files>>,
root: &Path,
host: Option<&str>,
) -> Self {
let session = session.unwrap_or_else(|| Arc::new(MemoryStore::default()));
Self {
session: Arc::new(PluginFiles(session)),
project: Arc::new(DirFiles::new(project_dir(home, root, host))),
user: Arc::new(DirFiles::new(home.data())),
}
}
}
impl PluginData {
pub fn of(stores: &StoreOpener, dir: &SessionDir) -> Result<Arc<dyn Files>, SessionError> {
let store: Arc<dyn Files> = stores.open(dir)?;
Ok(Arc::new(PluginFiles(store)))
}
}
fn project_dir(home: &Home, root: &Path, host: Option<&str>) -> PathBuf {
let root = match host {
None => root.canonicalize().unwrap_or_else(|_| root.to_owned()),
Some(_) => root.to_owned(),
};
let mut place = host.map(|host| format!("{host}:")).unwrap_or_default();
place.push_str(&root.to_string_lossy());
let hash = content_hash(place.as_bytes()).0;
let name = root
.file_name()
.map(|name| name.to_string_lossy().into_owned())
.unwrap_or_default();
let key = hash.get(..8).unwrap_or(&hash);
home.projects().join(format!("{name}-{key}"))
}
#[cfg(test)]
mod tests;