diff --git a/src/actions/format.rs b/src/actions/format.rs index 0010961515f..9c2a0fb0ff4 100644 --- a/src/actions/format.rs +++ b/src/actions/format.rs @@ -22,9 +22,6 @@ use log::{log, debug}; use rustfmt_nightly::{Config, Session, Input}; use serde_json; -struct External<'a>(&'a Path, &'a Path); -struct Internal; - /// Specified which `rustfmt` to use. #[derive(Clone)] pub enum Rustfmt { @@ -43,81 +40,68 @@ impl From> for Rustfmt { } } - -pub trait Formatter { - fn format(&self, input: String, cfg: Config) -> Result; -} - -impl Formatter for External<'_> { - fn format(&self, input: String, cfg: Config) -> Result { - let External(path, cwd) = self; - - let (_file_handle, config_path) = gen_config_file(&cfg)?; - let args = rustfmt_args(&cfg, &config_path); - - let mut rustfmt = Command::new(path) - .args(args) - .current_dir(cwd) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .map_err(|_| format!("Couldn't spawn `{}`", path.display()))?; - - { - let stdin = rustfmt.stdin.as_mut() - .ok_or_else(|| "Failed to open rustfmt stdin".to_string())?; - stdin.write_all(input.as_bytes()) - .map_err(|_| "Failed to pass input to rustfmt".to_string())?; +impl Rustfmt { + pub fn format(&self, input: String, cfg: Config) -> Result { + match self { + Rustfmt::Internal => format_internal(input, cfg), + Rustfmt::External(path, cwd) => format_external(path, cwd, input, cfg), } - - rustfmt.wait_with_output() - .map_err(|err| format!("Error running rustfmt: {}", err)) - .and_then(|out| String::from_utf8(out.stdout) - .map_err(|_| "Formatted code is not valid UTF-8".to_string())) } } -impl Formatter for Internal { - fn format(&self, input: String, config: Config) -> Result { - let mut buf = Vec::::new(); +fn format_external(path: &PathBuf, cwd: &PathBuf, input: String, cfg: Config) -> Result { + let (_file_handle, config_path) = gen_config_file(&cfg)?; + let args = rustfmt_args(&cfg, &config_path); + + let mut rustfmt = Command::new(path) + .args(args) + .current_dir(cwd) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .map_err(|_| format!("Couldn't spawn `{}`", path.display()))?; + + { + let stdin = rustfmt.stdin.as_mut() + .ok_or_else(|| "Failed to open rustfmt stdin".to_string())?; + stdin.write_all(input.as_bytes()) + .map_err(|_| "Failed to pass input to rustfmt".to_string())?; + } + + rustfmt.wait_with_output() + .map_err(|err| format!("Error running rustfmt: {}", err)) + .and_then(|out| String::from_utf8(out.stdout) + .map_err(|_| "Formatted code is not valid UTF-8".to_string())) +} - { - let mut session = Session::new(config, Some(&mut buf)); +fn format_internal(input: String, config:Config) -> Result { + let mut buf = Vec::::new(); - match session.format(Input::Text(input)) { - Ok(report) => { - // Session::format returns Ok even if there are any errors, i.e., parsing errors. - if session.has_operational_errors() || session.has_parsing_errors() { - debug!( - "reformat: format_input failed: has errors, report = {}", - report - ); + { + let mut session = Session::new(config, Some(&mut buf)); - return Err("Reformat failed to complete successfully".into()); - } - } - Err(e) => { - debug!("Reformat failed: {:?}", e); + match session.format(Input::Text(input)) { + Ok(report) => { + // Session::format returns Ok even if there are any errors, i.e., parsing errors. + if session.has_operational_errors() || session.has_parsing_errors() { + debug!( + "reformat: format_input failed: has errors, report = {}", + report + ); return Err("Reformat failed to complete successfully".into()); } } - } - - String::from_utf8(buf) - .map_err(|_| "Reformat output is not a valid UTF-8".into()) - } -} + Err(e) => { + debug!("Reformat failed: {:?}", e); -impl Formatter for Rustfmt { - fn format(&self, input: String, cfg: Config) -> Result { - match self { - Rustfmt::Internal => Internal.format(input, cfg), - Rustfmt::External(path, cwd) => { - External(path.as_path(), cwd.as_path()).format(input, cfg) + return Err("Reformat failed to complete successfully".into()); } } } + + String::from_utf8(buf) + .map_err(|_| "Reformat output is not a valid UTF-8".into()) } fn random_file() -> Result<(File, PathBuf), String> { diff --git a/src/actions/hover.rs b/src/actions/hover.rs index 54182b95a44..8be71968687 100644 --- a/src/actions/hover.rs +++ b/src/actions/hover.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::actions::format::{Rustfmt, Formatter}; +use crate::actions::format::Rustfmt; use crate::actions::requests; use crate::actions::InitActionContext; use crate::config::FmtConfig; diff --git a/src/actions/mod.rs b/src/actions/mod.rs index de398d3d0df..12e2eb65e8a 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -270,9 +270,9 @@ impl InitActionContext { racer::Session::with_project_model(cache, pm) } - /// Since external Rustfmt can be specified, this returns an enum specifying - /// which one to use and which implements the String-formatting `Formatter` - /// trait. + /// Depending on user configuration, we might use either external Rustfmt or + /// the one we're shipping with. + /// Locks config to read `rustfmt_path` key. fn formatter(&self) -> Rustfmt { let rustfmt = self.config.lock().unwrap().rustfmt_path.clone() .map(|path| (path, self.current_project.clone())); diff --git a/src/actions/requests.rs b/src/actions/requests.rs index f55b9fd2814..67d69edb44c 100644 --- a/src/actions/requests.rs +++ b/src/actions/requests.rs @@ -22,7 +22,6 @@ use itertools::Itertools; use serde_derive::{Serialize, Deserialize}; use log::{debug, log, trace}; -use crate::actions::format::Formatter; use crate::actions::hover; use crate::actions::work_pool; use crate::actions::work_pool::WorkDescription;