use fallow_config::WorkspaceInfo;
use fallow_types::discover::{DiscoveredFile, FileId};
pub struct ProjectState {
files: Vec<DiscoveredFile>,
workspaces: Vec<WorkspaceInfo>,
}
impl ProjectState {
#[must_use]
pub fn new(files: Vec<DiscoveredFile>, workspaces: Vec<WorkspaceInfo>) -> Self {
debug_assert!(
files.iter().enumerate().all(|(i, f)| f.id.0 as usize == i),
"FileIds must be densely packed starting at 0"
);
Self { files, workspaces }
}
#[must_use]
pub fn files(&self) -> &[DiscoveredFile] {
&self.files
}
#[must_use]
pub fn workspaces(&self) -> &[WorkspaceInfo] {
&self.workspaces
}
#[must_use]
pub fn file_by_id(&self, id: FileId) -> Option<&DiscoveredFile> {
self.files.get(id.0 as usize)
}
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use super::*;
fn make_file(id: u32, path: &str) -> DiscoveredFile {
DiscoveredFile {
id: FileId(id),
path: PathBuf::from(path),
size_bytes: 100,
}
}
fn make_workspace(name: &str, root: &str) -> WorkspaceInfo {
WorkspaceInfo {
root: PathBuf::from(root),
name: name.to_string(),
is_internal_dependency: false,
}
}
#[test]
fn file_by_id_valid() {
let files = vec![
make_file(0, "/project/src/a.ts"),
make_file(1, "/project/src/b.ts"),
];
let state = ProjectState::new(files, vec![]);
let file = state.file_by_id(FileId(0)).unwrap();
assert_eq!(file.path, PathBuf::from("/project/src/a.ts"));
assert_eq!(file.id, FileId(0));
}
#[test]
fn file_by_id_out_of_bounds() {
let files = vec![make_file(0, "/project/src/a.ts")];
let state = ProjectState::new(files, vec![]);
assert!(state.file_by_id(FileId(999)).is_none());
}
#[test]
fn empty_state() {
let state = ProjectState::new(vec![], vec![]);
assert!(state.files().is_empty());
assert!(state.workspaces().is_empty());
assert!(state.file_by_id(FileId(0)).is_none());
}
#[test]
fn files_returns_all_files() {
let files = vec![
make_file(0, "/project/src/a.ts"),
make_file(1, "/project/src/b.ts"),
];
let state = ProjectState::new(files, vec![]);
assert_eq!(state.files().len(), 2);
assert_eq!(state.files()[0].id, FileId(0));
assert_eq!(state.files()[1].id, FileId(1));
}
#[test]
fn workspaces_returns_all_workspaces() {
let workspaces = vec![
make_workspace("a", "/project/packages/a"),
make_workspace("b", "/project/packages/b"),
];
let state = ProjectState::new(vec![], workspaces);
assert_eq!(state.workspaces().len(), 2);
}
}