From 422ae477ce2a52c8d004ce629318f0b7c1d89638 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 16 Apr 2020 22:19:38 +0200 Subject: Unmix error handling when discovering workspaces Hitting an io::Error is a legit problem. Finding more than one Cargo.toml is not. --- crates/ra_project_model/src/lib.rs | 78 +++++++++++--------------------------- 1 file changed, 23 insertions(+), 55 deletions(-) (limited to 'crates/ra_project_model/src') diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index df4be94dc..03f2629da 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -5,9 +5,8 @@ mod json_project; mod sysroot; use std::{ - error::Error, fs::{read_dir, File, ReadDir}, - io::BufReader, + io::{self, BufReader}, path::{Path, PathBuf}, process::Command, }; @@ -25,25 +24,6 @@ pub use crate::{ }; pub use ra_proc_macro::ProcMacroClient; -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct CargoTomlNotFoundError { - pub searched_at: PathBuf, - pub reason: String, -} - -impl std::fmt::Display for CargoTomlNotFoundError { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - fmt, - "can't find Cargo.toml at {}, due to {}", - self.searched_at.display(), - self.reason - ) - } -} - -impl Error for CargoTomlNotFoundError {} - #[derive(Debug, Clone)] pub enum ProjectWorkspace { /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. @@ -94,11 +74,25 @@ impl ProjectRoot { bail!("project root must point to Cargo.toml or rust-project.json: {}", path.display()) } - pub fn discover(path: &Path) -> Result { + pub fn discover_single(path: &Path) -> Result { + let mut candidates = ProjectRoot::discover(path)?; + let res = match candidates.pop() { + None => bail!("no projects"), + Some(it) => it, + }; + + if !candidates.is_empty() { + bail!("more than one project") + } + Ok(res) + } + + pub fn discover(path: &Path) -> io::Result> { if let Some(project_json) = find_rust_project_json(path) { - return Ok(ProjectRoot::ProjectJson(project_json)); + return Ok(vec![ProjectRoot::ProjectJson(project_json)]); } - return find_cargo_toml(path).map(ProjectRoot::CargoToml); + return find_cargo_toml(path) + .map(|paths| paths.into_iter().map(ProjectRoot::CargoToml).collect()); fn find_rust_project_json(path: &Path) -> Option { if path.ends_with("rust-project.json") { @@ -117,43 +111,17 @@ impl ProjectRoot { None } - fn find_cargo_toml(path: &Path) -> Result { + fn find_cargo_toml(path: &Path) -> io::Result> { if path.ends_with("Cargo.toml") { - return Ok(path.to_path_buf()); + return Ok(vec![path.to_path_buf()]); } if let Some(p) = find_cargo_toml_in_parent_dir(path) { - return Ok(p); + return Ok(vec![p]); } - let entities = match read_dir(path) { - Ok(entities) => entities, - Err(e) => { - return Err(CargoTomlNotFoundError { - searched_at: path.to_path_buf(), - reason: format!("file system error: {}", e), - } - .into()); - } - }; - - let mut valid_canditates = find_cargo_toml_in_child_dir(entities); - return match valid_canditates.len() { - 1 => Ok(valid_canditates.remove(0)), - 0 => Err(CargoTomlNotFoundError { - searched_at: path.to_path_buf(), - reason: "no Cargo.toml file found".to_string(), - } - .into()), - _ => Err(CargoTomlNotFoundError { - searched_at: path.to_path_buf(), - reason: format!( - "multiple equally valid Cargo.toml files found: {:?}", - valid_canditates - ), - } - .into()), - }; + let entities = read_dir(path)?; + Ok(find_cargo_toml_in_child_dir(entities)) } fn find_cargo_toml_in_parent_dir(path: &Path) -> Option { -- cgit v1.2.3