diff --git a/src/formats.rs b/src/formats.rs index 983f8bf..3f05570 100644 --- a/src/formats.rs +++ b/src/formats.rs @@ -12,21 +12,52 @@ const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION"); type Entries = [Result]; -fn write_pathbuf(f: &mut W, path: &PathBuf) -> io::Result<()> { - match path.to_str() { - Some(string) => { - write!(f, "{}", escape(string)) - } - None => { - write!(f, "'")?; - #[cfg(unix)] - f.write_all(&*path.as_os_str().as_bytes())?; - #[cfg(windows)] - write!(f, "{}", path.as_os_str().to_string_lossy())?; // TODO: implement bonked strings for windows - // f.write_all(&*path.as_os_str().encode_wide().collect::>())?; - write!(f, "'") +enum Writable<'a> { + String(&'a str), + Path(&'a PathBuf), + Space, + Newline +} + +// the lifetime of a lifetime +impl<'a> From<&'a str> for Writable<'a> { + fn from(s: &'a str) -> Writable<'a> { + Writable::String(s) + } +} + +impl<'a> From<&'a PathBuf> for Writable<'a> { + fn from(p: &'a PathBuf) -> Writable<'a> { + Writable::Path(p) + } +} + +fn smart_write(f: &mut W, writeables: &[Writable]) -> io::Result<()> { + // ehhhh + for writeable in writeables { + match writeable { + Writable::Space => write!(f, " ")?, + Writable::Newline => writeln!(f, )?, + Writable::String(s) => write!(f, "{}", s)?, + Writable::Path(path) => { + match path.to_str() { + Some(string) => { + write!(f, "{}", escape(string))? + } + None => { + write!(f, "'''")?; + #[cfg(unix)] + f.write_all(&*path.as_os_str().as_bytes())?; + #[cfg(windows)] + write!(f, "{}", path.as_os_str().to_string_lossy())?; // TODO: implement bonked strings for windows + // f.write_all(&*path.as_os_str().encode_wide().collect::>())?; + write!(f, "'''")? + } + } + } } } + Ok(()) } pub trait Format { @@ -39,22 +70,19 @@ pub trait Format { fn footer(&self, entries: &Entries, f: &mut W) -> io::Result<()>; fn write_all(&self, entries: &Entries, f: &mut W) -> io::Result<()> { - // TODO: clean this up - it's horrifying + // TODO: clean this up - it's kinda messy self.header(entries, f)?; for entry in entries { match entry { Ok(finding) => { - // the file was successfully scanned, and a mimetype was detected - if !finding.valid { - // the file's extension is wrong - check for known extension - if let Some(ext) = finding.recommended_extension() { - self.rename(f, &finding.file, &finding.file.with_extension(ext.as_str()))? - } else { - self.no_known_extension(f, &finding.file)? - } + if let Some(ext) = finding.recommended_extension() { + self.rename(f, &finding.file, &finding.file.with_extension(ext.as_str()))? + } else { + self.no_known_extension(f, &finding.file)? } } + Err(error) => { // something went wrong 0uo match error.0 { @@ -80,30 +108,37 @@ impl Format for Script { } fn rename(&self, f: &mut W, from: &PathBuf, to: &PathBuf) -> io::Result<()> { - // TODO: surely there's a better way... - write!(f, "mv -v -i -- ")?; - write_pathbuf(f, from)?; - write!(f, " ")?; - write_pathbuf(f, to)?; - writeln!(f,) + smart_write(f, &[ + "mv -v -i -- ".into(), + from.into(), + Writable::Space, + to.into(), + Writable::Newline + ]) } fn no_known_extension(&self, f: &mut W, path: &PathBuf) -> io::Result<()> { - write!(f, "echo No known extension for ")?; - write_pathbuf(f, path)?; - writeln!(f,) + smart_write(f, &[ + "echo No known extension for ".into(), + path.into(), + Writable::Newline + ]) } fn unreadable(&self, f: &mut W, path: &PathBuf) -> io::Result<()> { - write!(f, "# Failed to read ")?; - write_pathbuf(f, path)?; - writeln!(f,) + smart_write(f, &[ + "# Failed to read ".into(), + path.into(), + Writable::Newline + ]) } fn unknown_type(&self, f: &mut W, path: &PathBuf) -> io::Result<()> { - write!(f, "# Failed to detect mime type for ")?; - write_pathbuf(f, path)?; - writeln!(f,) + smart_write(f, &[ + "# Failed to detect mime type for ".into(), + path.into(), + Writable::Newline + ]) } fn header(&self, _: &Entries, f: &mut W) -> io::Result<()> {