diff options
Diffstat (limited to 'crates/ra_project_model/src/lib.rs')
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 2aa9270c8..e36338860 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -3,9 +3,9 @@ | |||
3 | mod cargo_workspace; | 3 | mod cargo_workspace; |
4 | mod json_project; | 4 | mod json_project; |
5 | mod sysroot; | 5 | mod sysroot; |
6 | mod workspace_error; | ||
7 | 6 | ||
8 | use std::{ | 7 | use std::{ |
8 | error::Error, | ||
9 | fs::File, | 9 | fs::File, |
10 | io::BufReader, | 10 | io::BufReader, |
11 | path::{Path, PathBuf}, | 11 | path::{Path, PathBuf}, |
@@ -21,9 +21,27 @@ pub use crate::{ | |||
21 | cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, | 21 | cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, |
22 | json_project::JsonProject, | 22 | json_project::JsonProject, |
23 | sysroot::Sysroot, | 23 | sysroot::Sysroot, |
24 | workspace_error::WorkspaceError, | ||
25 | }; | 24 | }; |
26 | 25 | ||
26 | pub type Result<T> = ::std::result::Result<T, Box<dyn Error + Send + Sync>>; | ||
27 | |||
28 | #[derive(Clone, PartialEq, Eq, Hash)] | ||
29 | pub struct CargoTomlNotFoundError(pub PathBuf); | ||
30 | |||
31 | impl std::fmt::Display for CargoTomlNotFoundError { | ||
32 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
33 | write!(fmt, "can't find Cargo.toml at {}", self.0.display()) | ||
34 | } | ||
35 | } | ||
36 | |||
37 | impl std::fmt::Debug for CargoTomlNotFoundError { | ||
38 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
39 | write!(fmt, "can't find Cargo.toml at {}", self.0.display()) | ||
40 | } | ||
41 | } | ||
42 | |||
43 | impl Error for CargoTomlNotFoundError {} | ||
44 | |||
27 | #[derive(Debug, Clone)] | 45 | #[derive(Debug, Clone)] |
28 | pub enum ProjectWorkspace { | 46 | pub enum ProjectWorkspace { |
29 | /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. | 47 | /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. |
@@ -58,10 +76,7 @@ impl PackageRoot { | |||
58 | } | 76 | } |
59 | 77 | ||
60 | impl ProjectWorkspace { | 78 | impl ProjectWorkspace { |
61 | pub fn discover( | 79 | pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result<ProjectWorkspace> { |
62 | path: &Path, | ||
63 | cargo_features: &CargoFeatures, | ||
64 | ) -> Result<ProjectWorkspace, WorkspaceError> { | ||
65 | ProjectWorkspace::discover_with_sysroot(path, true, cargo_features) | 80 | ProjectWorkspace::discover_with_sysroot(path, true, cargo_features) |
66 | } | 81 | } |
67 | 82 | ||
@@ -69,16 +84,12 @@ impl ProjectWorkspace { | |||
69 | path: &Path, | 84 | path: &Path, |
70 | with_sysroot: bool, | 85 | with_sysroot: bool, |
71 | cargo_features: &CargoFeatures, | 86 | cargo_features: &CargoFeatures, |
72 | ) -> Result<ProjectWorkspace, WorkspaceError> { | 87 | ) -> Result<ProjectWorkspace> { |
73 | match find_rust_project_json(path) { | 88 | match find_rust_project_json(path) { |
74 | Some(json_path) => { | 89 | Some(json_path) => { |
75 | let file = | 90 | let file = File::open(json_path)?; |
76 | File::open(json_path).map_err(|err| WorkspaceError::OpenWorkspaceError(err))?; | ||
77 | let reader = BufReader::new(file); | 91 | let reader = BufReader::new(file); |
78 | Ok(ProjectWorkspace::Json { | 92 | Ok(ProjectWorkspace::Json { project: from_reader(reader)? }) |
79 | project: from_reader(reader) | ||
80 | .map_err(|err| WorkspaceError::ReadWorkspaceError(err))?, | ||
81 | }) | ||
82 | } | 93 | } |
83 | None => { | 94 | None => { |
84 | let cargo_toml = find_cargo_toml(path)?; | 95 | let cargo_toml = find_cargo_toml(path)?; |
@@ -355,7 +366,7 @@ fn find_rust_project_json(path: &Path) -> Option<PathBuf> { | |||
355 | None | 366 | None |
356 | } | 367 | } |
357 | 368 | ||
358 | fn find_cargo_toml(path: &Path) -> Result<PathBuf, WorkspaceError> { | 369 | fn find_cargo_toml(path: &Path) -> Result<PathBuf> { |
359 | if path.ends_with("Cargo.toml") { | 370 | if path.ends_with("Cargo.toml") { |
360 | return Ok(path.to_path_buf()); | 371 | return Ok(path.to_path_buf()); |
361 | } | 372 | } |
@@ -367,7 +378,7 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf, WorkspaceError> { | |||
367 | } | 378 | } |
368 | curr = path.parent(); | 379 | curr = path.parent(); |
369 | } | 380 | } |
370 | Err(WorkspaceError::CargoTomlNotFound(path.to_path_buf())) | 381 | Err(Box::new(CargoTomlNotFoundError(path.to_path_buf()))) |
371 | } | 382 | } |
372 | 383 | ||
373 | pub fn get_rustc_cfg_options() -> CfgOptions { | 384 | pub fn get_rustc_cfg_options() -> CfgOptions { |
@@ -381,16 +392,13 @@ pub fn get_rustc_cfg_options() -> CfgOptions { | |||
381 | } | 392 | } |
382 | } | 393 | } |
383 | 394 | ||
384 | match (|| -> Result<_, WorkspaceError> { | 395 | match (|| -> Result<_> { |
385 | // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. | 396 | // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. |
386 | let output = Command::new("rustc") | 397 | let output = Command::new("rustc").args(&["--print", "cfg", "-O"]).output()?; |
387 | .args(&["--print", "cfg", "-O"]) | ||
388 | .output() | ||
389 | .map_err(|err| WorkspaceError::RustcError(err))?; | ||
390 | if !output.status.success() { | 398 | if !output.status.success() { |
391 | Err(WorkspaceError::RustcCfgError)?; | 399 | Err("failed to get rustc cfgs")?; |
392 | } | 400 | } |
393 | Ok(String::from_utf8(output.stdout).map_err(|err| WorkspaceError::RustcOutputError(err))?) | 401 | Ok(String::from_utf8(output.stdout)?) |
394 | })() { | 402 | })() { |
395 | Ok(rustc_cfgs) => { | 403 | Ok(rustc_cfgs) => { |
396 | for line in rustc_cfgs.lines() { | 404 | for line in rustc_cfgs.lines() { |