use std::collections::BTreeMap;
use crate::name::{OverlayName, ProjectName};
use crate::overlay::Overlay;
use crate::path::WorkspaceRootPath;
use crate::project::Project;
use crate::settings::WorkspaceSettings;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Workspace {
pub root: WorkspaceRootPath,
pub projects: BTreeMap<ProjectName, Project>,
pub overlays: BTreeMap<OverlayName, Overlay>,
pub settings: WorkspaceSettings,
}
#[cfg(test)]
mod tests {
use std::collections::{BTreeMap, BTreeSet};
use std::path::PathBuf;
use std::str::FromStr;
use crate::name::ProjectName;
use crate::path::{CanonicalPath, HazPath, ProjectRoot, WorkspaceRootPath};
use crate::project::Project;
use crate::workspace::Workspace;
fn project(name: &str, root: &str) -> Project {
Project {
name: ProjectName::from_str(name).unwrap(),
root: ProjectRoot::Nested(
CanonicalPath::from_absolute(&HazPath::parse(root).unwrap()).unwrap(),
),
tags: BTreeSet::new(),
tasks: BTreeMap::new(),
}
}
#[cfg(unix)]
#[test]
fn workspace_with_projects() {
use crate::settings::WorkspaceSettings;
let mut projects = BTreeMap::new();
let p1 = project("lib_core", "/lib_core");
let p2 = project("web_frontend", "/web/frontend");
projects.insert(p1.name.clone(), p1);
projects.insert(p2.name.clone(), p2);
let ws = Workspace {
root: WorkspaceRootPath::try_new(PathBuf::from("/abs/workspace")).unwrap(),
projects,
overlays: BTreeMap::new(),
settings: WorkspaceSettings::default(),
};
assert_eq!(ws.projects.len(), 2);
assert!(ws.overlays.is_empty());
}
#[cfg(unix)]
#[test]
fn workspace_with_overlays() {
use std::str::FromStr;
use crate::name::{OverlayName, TaskName};
use crate::overlay::Overlay;
use crate::settings::WorkspaceSettings;
let mut projects = BTreeMap::new();
let p = project("lib_core", "/lib_core");
projects.insert(p.name.clone(), p);
let mut overlays = BTreeMap::new();
let lint = Overlay {
name: OverlayName::from_str("lint").unwrap(),
matched_projects: BTreeSet::from([ProjectName::from_str("lib_core").unwrap()]),
tasks: BTreeMap::new(),
};
overlays.insert(lint.name.clone(), lint);
let ws = Workspace {
root: WorkspaceRootPath::try_new(PathBuf::from("/abs/workspace")).unwrap(),
projects,
overlays,
settings: WorkspaceSettings::default(),
};
assert_eq!(ws.projects.len(), 1);
assert_eq!(ws.overlays.len(), 1);
assert!(
ws.overlays
.contains_key(&OverlayName::from_str("lint").unwrap())
);
assert!(
ws.overlays
.values()
.next()
.unwrap()
.tasks
.keys()
.all(|_: &TaskName| true)
);
}
#[test]
fn workspace_project_uniqueness_is_structural() {
let mut projects = BTreeMap::new();
let p1 = project("lib_core", "/lib_core");
let key = p1.name.clone();
let inserted_first = projects.insert(key.clone(), p1);
assert!(inserted_first.is_none());
let inserted_again = projects.insert(key, project("lib_core", "/lib_core"));
assert!(inserted_again.is_some());
assert_eq!(projects.len(), 1);
}
#[test]
fn workspace_overlay_uniqueness_is_structural() {
use std::str::FromStr;
use crate::name::OverlayName;
use crate::overlay::Overlay;
let mut overlays = BTreeMap::new();
let lint = Overlay {
name: OverlayName::from_str("lint").unwrap(),
matched_projects: BTreeSet::new(),
tasks: BTreeMap::new(),
};
let key = lint.name.clone();
let inserted_first = overlays.insert(key.clone(), lint);
assert!(inserted_first.is_none());
let inserted_again = overlays.insert(
key,
Overlay {
name: OverlayName::from_str("lint").unwrap(),
matched_projects: BTreeSet::new(),
tasks: BTreeMap::new(),
},
);
assert!(inserted_again.is_some());
assert_eq!(overlays.len(), 1);
}
}