use std::path::{Path, PathBuf};
use std::sync::{Arc, RwLock};
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct WorkspaceFolder {
pub root: PathBuf,
pub name: String,
}
impl WorkspaceFolder {
#[must_use]
pub fn new(root: impl Into<PathBuf>, name: impl Into<String>) -> Self {
Self {
root: root.into(),
name: name.into(),
}
}
}
#[derive(Debug, Clone, Default)]
pub struct Workspace {
folders: Arc<RwLock<Vec<WorkspaceFolder>>>,
}
impl Workspace {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn set_folders(&self, folders: Vec<WorkspaceFolder>) {
if let Ok(mut guard) = self.folders.write() {
*guard = folders;
}
}
pub fn add(&self, folder: WorkspaceFolder) {
if let Ok(mut guard) = self.folders.write() {
guard.push(folder);
}
}
pub fn remove(&self, root: &Path) {
if let Ok(mut guard) = self.folders.write() {
guard.retain(|f| f.root != root);
}
}
#[must_use]
pub fn folders(&self) -> Vec<WorkspaceFolder> {
self.folders
.read()
.map_or_else(|_| Vec::new(), |g| g.clone())
}
#[must_use]
pub fn folder_for(&self, path: &Path) -> Option<WorkspaceFolder> {
self.folders
.read()
.ok()
.and_then(|guard| guard.iter().find(|f| path.starts_with(&f.root)).cloned())
}
#[must_use]
pub fn len(&self) -> usize {
self.folders.read().map_or(0, |g| g.len())
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}