From d815a755a82f9ee90b598bc9dc88ef06f5d66f5e Mon Sep 17 00:00:00 2001 From: root Date: Wed, 25 May 2022 12:16:57 +0000 Subject: move to osstr --- src/displace.rs | 28 +++++++++++++++++----------- src/fs_pipe.rs | 5 +++++ src/fzf.rs | 5 +++-- src/main.rs | 6 +++--- src/output.rs | 6 +++--- src/subprocess.rs | 17 +++++++++++++---- src/udiff.rs | 46 ++++++++++++++++++++++++++++++---------------- src/udiff_spec.rs | 4 +++- 8 files changed, 77 insertions(+), 40 deletions(-) diff --git a/src/displace.rs b/src/displace.rs index 0df7351..23e6473 100644 --- a/src/displace.rs +++ b/src/displace.rs @@ -7,7 +7,7 @@ use { udiff::{apply_patches, patches, pure_diffs, udiff}, }, ansi_term::Colour, - std::{path::PathBuf, sync::Arc}, + std::{ffi::OsString, path::PathBuf, sync::Arc}, tokio::task::spawn_blocking, }; @@ -28,15 +28,16 @@ impl Payload { } } -pub async fn displace(opts: &Arc, payload: Payload) -> Result { +pub async fn displace(opts: &Arc, payload: Payload) -> Result { let path = payload.path().clone(); - let rel_path = opts + let name = opts .cwd .as_ref() .and_then(|cwd| path.strip_prefix(cwd).ok()) - .unwrap_or_else(|| path.as_ref()); + .unwrap_or_else(|| path.as_ref()) + .as_os_str() + .to_owned(); - let name = format!("{}", rel_path.display()); let slurped = slurp(&path).await?; let before = Arc::new(slurped.content); @@ -46,7 +47,7 @@ pub async fn displace(opts: &Arc, payload: Payload) -> Result { @@ -57,7 +58,9 @@ pub async fn displace(opts: &Arc, payload: Payload) -> Result { spit(&path, &slurped.meta, &after).await?; - format!("{name}\n") + let mut out = OsString::from(name); + out.push("\n"); + out } (Action::Commit, Payload::Piecewise(_, ranges)) => { let after = spawn_blocking(move || { @@ -67,16 +70,19 @@ pub async fn displace(opts: &Arc, payload: Payload) -> Result { spawn_blocking(move || { let ranges = pure_diffs(o2.unified, &before, &after); - let mut fzf_lines = String::new(); + let mut fzf_lines = OsString::new(); for range in ranges { let repr = Colour::Red.paint(format!("{range}")); - let line = format!("{name}\n\n\n\n{repr}\0"); - fzf_lines.push_str(&line); + fzf_lines.push(&name); + let line = format!("\n\n\n\n{repr}\0"); + fzf_lines.push(&line); } fzf_lines }) diff --git a/src/fs_pipe.rs b/src/fs_pipe.rs index 6927ae4..d3bdd93 100644 --- a/src/fs_pipe.rs +++ b/src/fs_pipe.rs @@ -63,6 +63,11 @@ pub async fn spit(canonical: &Path, meta: &Metadata, text: &str) -> Result<(), F .await .map_err(|e| Fail::IO(tmp.clone(), e.kind()))?; + writer + .flush() + .await + .map_err(|e| Fail::IO(tmp.clone(), e.kind()))?; + rename(&tmp, &canonical) .await .map_err(|e| Fail::IO(canonical.to_owned(), e.kind()))?; diff --git a/src/fzf.rs b/src/fzf.rs index 12d35d0..e1eb04b 100644 --- a/src/fzf.rs +++ b/src/fzf.rs @@ -8,6 +8,7 @@ use { std::{ collections::HashMap, env::{self, current_exe}, + ffi::OsString, path::PathBuf, process::Stdio, sync::Arc, @@ -50,7 +51,7 @@ async fn reset_term() -> Result<(), Fail> { Err(Fail::IO(PathBuf::from("reset"), ErrorKind::NotFound)) } -fn run_fzf(abort: &Arc, cmd: SubprocCommand, stream: Receiver) -> JoinHandle<()> { +fn run_fzf(abort: &Arc, cmd: SubprocCommand, stream: Receiver) -> JoinHandle<()> { let abort = abort.clone(); spawn(async move { @@ -129,7 +130,7 @@ pub fn stream_fzf_proc( abort: &Arc, bin: PathBuf, args: Vec, - stream: Receiver, + stream: Receiver, ) -> JoinHandle<()> { let execute = format!("abort+execute:{}\x04{{+f}}", Mode::PATCH); let mut arguments = vec![ diff --git a/src/main.rs b/src/main.rs index 074bce7..1f0e662 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,7 @@ use { }, input::{stream_in, Payload}, output::stream_out, - std::{convert::Into, process::exit, sync::Arc, thread::available_parallelism}, + std::{convert::Into, ffi::OsString, process::exit, sync::Arc, thread::available_parallelism}, tokio::{ runtime::Builder, sync::mpsc::{self, Receiver}, @@ -37,9 +37,9 @@ fn stream_trans( threads: usize, opts: &Options, stream: &MPMCR, -) -> (JoinHandle<()>, Receiver) { +) -> (JoinHandle<()>, Receiver) { let a_opts = Arc::new(opts.clone()); - let (tx, rx) = mpsc::channel::(1); + let (tx, rx) = mpsc::channel::(1); let handles = (1..=threads * 2) .map(|_| { diff --git a/src/output.rs b/src/output.rs index bd3a53d..1758d13 100644 --- a/src/output.rs +++ b/src/output.rs @@ -5,7 +5,7 @@ use { subprocess::{stream_into, stream_subproc}, types::{Abort, Fail}, }, - std::{path::PathBuf, sync::Arc}, + std::{ffi::OsString, path::PathBuf, sync::Arc}, tokio::{ io::{self, AsyncWriteExt, BufWriter}, sync::mpsc::Receiver, @@ -13,7 +13,7 @@ use { }, }; -fn stream_stdout(abort: &Arc, stream: Receiver) -> JoinHandle<()> { +fn stream_stdout(abort: &Arc, stream: Receiver) -> JoinHandle<()> { let abort = abort.clone(); let mut stdout = BufWriter::new(io::stdout()); @@ -27,7 +27,7 @@ fn stream_stdout(abort: &Arc, stream: Receiver) -> JoinHandle<()> }) } -pub fn stream_out(abort: &Arc, opts: &Options, stream: Receiver) -> JoinHandle<()> { +pub fn stream_out(abort: &Arc, opts: &Options, stream: Receiver) -> JoinHandle<()> { match (&opts.action, &opts.printer) { (Action::FzfPreview(fzf_p, fzf_a), _) => { stream_fzf_proc(abort, fzf_p.clone(), fzf_a.clone(), stream) diff --git a/src/subprocess.rs b/src/subprocess.rs index cf8d76b..5227ec9 100644 --- a/src/subprocess.rs +++ b/src/subprocess.rs @@ -4,7 +4,7 @@ use { future::{select, try_join, Either}, pin_mut, }, - std::{collections::HashMap, path::PathBuf, process::Stdio, sync::Arc}, + std::{collections::HashMap, ffi::OsString, path::PathBuf, process::Stdio, sync::Arc}, tokio::{ io::{AsyncWrite, AsyncWriteExt, BufWriter}, process::Command, @@ -24,7 +24,7 @@ pub async fn stream_into( abort: &Arc, path: PathBuf, writer: &mut BufWriter, - mut stream: Receiver, + mut stream: Receiver, ) { loop { let f1 = abort.notified(); @@ -33,7 +33,16 @@ pub async fn stream_into( pin_mut!(f2); match select(f1, f2).await { Either::Right((Some(print), _)) => { - if let Err(err) = writer.write_all(print.as_bytes()).await { + #[cfg(target_family = "unix")] + let bytes = { + use std::os::unix::ffi::OsStrExt; + print.as_bytes() + }; + #[cfg(target_family = "windows")] + let tmp = print.to_string_lossy(); + #[cfg(target_family = "windows")] + let bytes = tmp.as_bytes(); + if let Err(err) = writer.write_all(bytes).await { abort.send(Fail::IO(path, err.kind())).await; break; } @@ -46,7 +55,7 @@ pub async fn stream_into( pub fn stream_subproc( abort: &Arc, cmd: SubprocCommand, - stream: Receiver, + stream: Receiver, ) -> JoinHandle<()> { let abort = abort.clone(); diff --git a/src/udiff.rs b/src/udiff.rs index 709ad15..acc879c 100644 --- a/src/udiff.rs +++ b/src/udiff.rs @@ -2,6 +2,7 @@ use { difflib::{sequencematcher::Opcode, sequencematcher::SequenceMatcher}, std::{ collections::HashSet, + ffi::{OsStr, OsString}, fmt::{self, Display, Formatter}, }, }; @@ -121,17 +122,28 @@ pub fn apply_patches(patches: Vec, ranges: &HashSet, before: & pub fn udiff( ranges: Option<&HashSet>, unified: usize, - name: &str, + name: &OsStr, before: &str, after: &str, -) -> String { +) -> OsString { let before = before.split_inclusive('\n').collect::>(); let after = after.split_inclusive('\n').collect::>(); - let mut ret = String::new(); - ret.push_str(&format!("diff --git {name} {name}\n")); - ret.push_str(&format!("--- {name}\n")); - ret.push_str(&format!("+++ {name}\n")); + let mut ret = OsString::new(); + + ret.push("diff --git "); + ret.push(name); + ret.push(" "); + ret.push(name); + ret.push("\n"); + + ret.push("--- "); + ret.push(name); + ret.push("\n"); + + ret.push("+++ "); + ret.push(name); + ret.push("\n"); let mut matcher = SequenceMatcher::new(&before, &after); for group in &matcher.get_grouped_opcodes(unified) { @@ -141,25 +153,27 @@ pub fn udiff( continue; } }; - ret.push_str(&format!("{range}\n")); + + ret.push(&format!("{range}\n")); + for code in group { if code.tag == "equal" { - for line_ref in before.iter().take(code.first_end).skip(code.first_start) { - let line = *line_ref; - ret.push_str(&format!(" {line}")); + for line in before.iter().take(code.first_end).skip(code.first_start) { + ret.push(" "); + ret.push(*line); } continue; } if code.tag == "replace" || code.tag == "delete" { - for line_ref in before.iter().take(code.first_end).skip(code.first_start) { - let line = *line_ref; - ret.push_str(&format!("-{line}")); + for line in before.iter().take(code.first_end).skip(code.first_start) { + ret.push("-"); + ret.push(*line); } } if code.tag == "replace" || code.tag == "insert" { - for line_ref in after.iter().take(code.second_end).skip(code.second_start) { - let line = *line_ref; - ret.push_str(&format!("+{line}")); + for line in after.iter().take(code.second_end).skip(code.second_start) { + ret.push("+"); + ret.push(*line); } } } diff --git a/src/udiff_spec.rs b/src/udiff_spec.rs index 00d2242..69d3df9 100644 --- a/src/udiff_spec.rs +++ b/src/udiff_spec.rs @@ -5,6 +5,7 @@ mod udiff_spec { use regex::Regex; use std::{ collections::HashSet, + ffi::OsStr, fs::{read_dir, read_to_string}, path::PathBuf, }; @@ -100,7 +101,8 @@ mod udiff_spec { } }) .collect::>(); - let imp = udiff(None, unified, "", &before, &after) + let imp = udiff(None, unified, &OsStr::new(""), &before, &after) + .to_string_lossy() .split_inclusive("\n") .skip(3) .map(|s| { -- cgit v1.2.3