1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use super::prelude::{File, Index, IndexList, Pid, Project, Strategy, Timeline};
use std::collections::HashMap;
use std::path::Path;
pub trait Workspace {
type Project: Project;
type File: File;
fn projects(&self) -> &[Self::Project];
fn strategy(&self, index: &Index) -> Strategy;
fn file(path: &Path, pid: Pid) -> Option<Self::File>;
fn formatter(pid: &Pid, filename: &str) -> String {
format!("{}_{}", filename, pid.value())
}
fn resolve(&self) -> Timeline<Self>
where
Self: Sized,
{
let preview = preview(self);
let projects = project_paths(self);
let strategy = indexes(self)
.map(|index| {
let strategy = preview
.get_different_pid(index)
.map_or(Strategy::Replace, |_| self.strategy(index));
(index, strategy)
})
.collect();
Timeline::new(strategy, projects)
}
}
fn projects<W: Workspace>(workspace: &W) -> impl Iterator<Item = &W::Project> {
workspace.projects().iter()
}
fn indexes<W: Workspace>(workspace: &W) -> impl Iterator<Item = &Index> {
projects(workspace).flat_map(Project::indexes)
}
fn project_paths<W: Workspace>(workspace: &W) -> HashMap<Pid, &Path> {
projects(workspace).map(|p| (p.pid(), p.root())).collect()
}
fn preview<W: Workspace>(workspace: &W) -> IndexList {
indexes(workspace).collect()
}