diff options
author | Aleksey Kladov <[email protected]> | 2018-09-02 12:46:15 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-02 12:46:15 +0100 |
commit | 80be61ed78e8410e013cb94879435d54a4907c30 (patch) | |
tree | 3ab33c902644a3aa14b490be8a7caa9120da7537 /crates/server/src/project_model.rs | |
parent | 7fad13de73ded5b8a332c5f50c18671d612bd1e3 (diff) |
project model
Diffstat (limited to 'crates/server/src/project_model.rs')
-rw-r--r-- | crates/server/src/project_model.rs | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/crates/server/src/project_model.rs b/crates/server/src/project_model.rs index a33b34dd0..1c5954dad 100644 --- a/crates/server/src/project_model.rs +++ b/crates/server/src/project_model.rs | |||
@@ -2,30 +2,35 @@ use std::{ | |||
2 | collections::HashMap, | 2 | collections::HashMap, |
3 | path::{Path, PathBuf}, | 3 | path::{Path, PathBuf}, |
4 | }; | 4 | }; |
5 | use libsyntax2::SmolStr; | ||
6 | use cargo_metadata::{metadata_run, CargoOpt}; | 5 | use cargo_metadata::{metadata_run, CargoOpt}; |
7 | use Result; | 6 | use crossbeam_channel::{bounded, Sender, Receiver}; |
7 | use libsyntax2::SmolStr; | ||
8 | |||
9 | use { | ||
10 | Result, | ||
11 | thread_watcher::ThreadWatcher, | ||
12 | }; | ||
8 | 13 | ||
9 | #[derive(Debug)] | 14 | #[derive(Debug, Serialize, Clone)] |
10 | pub struct CargoWorkspace { | 15 | pub struct CargoWorkspace { |
11 | ws_members: Vec<Package>, | 16 | ws_members: Vec<Package>, |
12 | packages: Vec<PackageData>, | 17 | packages: Vec<PackageData>, |
13 | targets: Vec<TargetData>, | 18 | targets: Vec<TargetData>, |
14 | } | 19 | } |
15 | 20 | ||
16 | #[derive(Clone, Copy, Debug)] | 21 | #[derive(Clone, Copy, Debug, Serialize)] |
17 | pub struct Package(usize); | 22 | pub struct Package(usize); |
18 | #[derive(Clone, Copy, Debug)] | 23 | #[derive(Clone, Copy, Debug, Serialize)] |
19 | pub struct Target(usize); | 24 | pub struct Target(usize); |
20 | 25 | ||
21 | #[derive(Debug)] | 26 | #[derive(Debug, Serialize, Clone)] |
22 | struct PackageData { | 27 | struct PackageData { |
23 | name: SmolStr, | 28 | name: SmolStr, |
24 | manifest: PathBuf, | 29 | manifest: PathBuf, |
25 | targets: Vec<Target> | 30 | targets: Vec<Target> |
26 | } | 31 | } |
27 | 32 | ||
28 | #[derive(Debug)] | 33 | #[derive(Debug, Serialize, Clone)] |
29 | struct TargetData { | 34 | struct TargetData { |
30 | pkg: Package, | 35 | pkg: Package, |
31 | name: SmolStr, | 36 | name: SmolStr, |
@@ -33,7 +38,7 @@ struct TargetData { | |||
33 | kind: TargetKind, | 38 | kind: TargetKind, |
34 | } | 39 | } |
35 | 40 | ||
36 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 41 | #[derive(Debug, Serialize, Clone, Copy, PartialEq, Eq)] |
37 | pub enum TargetKind { | 42 | pub enum TargetKind { |
38 | Bin, Lib, Example, Test, Bench, Other, | 43 | Bin, Lib, Example, Test, Bench, Other, |
39 | } | 44 | } |
@@ -66,9 +71,10 @@ impl Target { | |||
66 | } | 71 | } |
67 | 72 | ||
68 | impl CargoWorkspace { | 73 | impl CargoWorkspace { |
69 | pub fn from_path(path: &Path) -> Result<CargoWorkspace> { | 74 | pub fn from_cargo_metadata(path: &Path) -> Result<CargoWorkspace> { |
75 | let cargo_toml = find_cargo_toml(path)?; | ||
70 | let meta = metadata_run( | 76 | let meta = metadata_run( |
71 | Some(path), | 77 | Some(cargo_toml.as_path()), |
72 | true, | 78 | true, |
73 | Some(CargoOpt::AllFeatures) | 79 | Some(CargoOpt::AllFeatures) |
74 | ).map_err(|e| format_err!("cargo metadata failed: {}", e))?; | 80 | ).map_err(|e| format_err!("cargo metadata failed: {}", e))?; |
@@ -121,6 +127,21 @@ impl CargoWorkspace { | |||
121 | } | 127 | } |
122 | } | 128 | } |
123 | 129 | ||
130 | fn find_cargo_toml(path: &Path) -> Result<PathBuf> { | ||
131 | if path.ends_with("Cargo.toml") { | ||
132 | return Ok(path.to_path_buf()); | ||
133 | } | ||
134 | let mut curr = Some(path); | ||
135 | while let Some(path) = curr { | ||
136 | let candidate = path.join("Cargo.toml"); | ||
137 | if candidate.exists() { | ||
138 | return Ok(candidate); | ||
139 | } | ||
140 | curr = path.parent(); | ||
141 | } | ||
142 | bail!("can't find Cargo.toml at {}", path.display()) | ||
143 | } | ||
144 | |||
124 | impl TargetKind { | 145 | impl TargetKind { |
125 | fn new(kinds: &[String]) -> TargetKind { | 146 | fn new(kinds: &[String]) -> TargetKind { |
126 | for kind in kinds { | 147 | for kind in kinds { |
@@ -136,3 +157,16 @@ impl TargetKind { | |||
136 | TargetKind::Other | 157 | TargetKind::Other |
137 | } | 158 | } |
138 | } | 159 | } |
160 | |||
161 | pub fn workspace_loader() -> (Sender<PathBuf>, Receiver<Result<CargoWorkspace>>, ThreadWatcher) { | ||
162 | let (path_sender, path_receiver) = bounded::<PathBuf>(16); | ||
163 | let (ws_sender, ws_receiver) = bounded::<Result<CargoWorkspace>>(1); | ||
164 | let thread = ThreadWatcher::spawn("workspace loader", move || { | ||
165 | path_receiver | ||
166 | .into_iter() | ||
167 | .map(|path| CargoWorkspace::from_cargo_metadata(path.as_path())) | ||
168 | .for_each(|it| ws_sender.send(it)) | ||
169 | }); | ||
170 | |||
171 | (path_sender, ws_receiver, thread) | ||
172 | } | ||