Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Commit

Permalink
Replace Formatter trait with inherent impl
Browse files Browse the repository at this point in the history
  • Loading branch information
Xanewok committed Aug 27, 2018
1 parent f5710b0 commit 3dc4592
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 68 deletions.
110 changes: 47 additions & 63 deletions src/actions/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -43,81 +40,68 @@ impl From<Option<(String, PathBuf)>> for Rustfmt {
}
}


pub trait Formatter {
fn format(&self, input: String, cfg: Config) -> Result<String, String>;
}

impl Formatter for External<'_> {
fn format(&self, input: String, cfg: Config) -> Result<String, String> {
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<String, String> {
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<String, String> {
let mut buf = Vec::<u8>::new();
fn format_external(path: &PathBuf, cwd: &PathBuf, input: String, cfg: Config) -> Result<String, String> {
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<String, String> {
let mut buf = Vec::<u8>::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<String, String> {
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> {
Expand Down
2 changes: 1 addition & 1 deletion src/actions/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/actions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down
1 change: 0 additions & 1 deletion src/actions/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 3dc4592

Please sign in to comment.