added rustfmt.toml, ran rustfmt

This commit is contained in:
Lynne Megido 2021-02-18 19:48:38 +10:00
parent 31acd76c73
commit b6d340d45c
Signed by: lynnesbian
GPG key ID: F0A184B5213D9F90
7 changed files with 94 additions and 74 deletions

4
rusftmt.toml Normal file
View file

@ -0,0 +1,4 @@
max_width = 120
hard_tabs = true
tab_spaces = 2
newline_style = "Unix"

View file

@ -1,8 +1,10 @@
use std::path::PathBuf;
use crate::inspectors::mime_extension_lookup;
use mime_guess::Mime;
use smartstring::alias::String;
use crate::inspectors::mime_extension_lookup;
pub struct Findings {
pub file: PathBuf, // TODO: replace with Path???? <'a> and all that
pub valid: bool,
@ -11,7 +13,6 @@ pub struct Findings {
impl Findings {
pub fn recommended_extension(&self) -> Option<String> {
mime_extension_lookup(self.mime.clone())
.map(|extensions| extensions[0].to_owned())
mime_extension_lookup(self.mime.clone()).map(|extensions| extensions[0].to_owned())
}
}

View file

@ -16,13 +16,15 @@ type Entries = [Result<Findings, (ScanError, PathBuf)>];
fn write_pathbuf<W: Write>(f: &mut W, path: &PathBuf) -> io::Result<()> {
match path.to_str() {
Some(string) => { write!(f, "{}", escape(string)) }
Some(string) => {
write!(f, "{}", escape(string))
}
None => {
write!(f, "'")?;
#[cfg(unix)]
f.write_all(&*path.as_os_str().as_bytes())?;
f.write_all(&*path.as_os_str().as_bytes())?;
#[cfg(windows)]
f.write_all(&*path.as_os_str().encode_wide().collect())?; // TODO: TEST THIS
f.write_all(&*path.as_os_str().encode_wide().collect())?; // TODO: TEST THIS
write!(f, "'")
}
}
@ -48,11 +50,7 @@ pub trait Format {
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()),
)?
self.rename(f, &finding.file, &finding.file.with_extension(ext.as_str()))?
} else {
self.no_known_extension(f, &finding.file)?
}
@ -64,7 +62,7 @@ pub trait Format {
// failed to read the file
ScanError::File => self.unreadable(f, &error.1)?,
// file was read successfully, but we couldn't determine a mimetype
ScanError::Mime => self.unknown_type(f, &error.1)?
ScanError::Mime => self.unknown_type(f, &error.1)?,
}
}
}
@ -77,7 +75,9 @@ pub trait Format {
pub struct Script {}
impl Format for Script {
fn new() -> Self { Self {} }
fn new() -> Self {
Self {}
}
fn rename<W: Write>(&self, f: &mut W, from: &PathBuf, to: &PathBuf) -> io::Result<()> {
// TODO: surely there's a better way...
@ -85,29 +85,33 @@ impl Format for Script {
write_pathbuf(f, from)?;
write!(f, " ")?;
write_pathbuf(f, to)?;
writeln!(f, )
writeln!(f,)
}
fn no_known_extension<W: Write>(&self, f: &mut W, path: &PathBuf) -> io::Result<()> {
write!(f, "echo No known extension for ")?;
write_pathbuf(f, path)?;
writeln!(f, )
writeln!(f,)
}
fn unreadable<W: Write>(&self, f: &mut W, path: &PathBuf) -> io::Result<()> {
write!(f, "# Failed to read ")?;
write_pathbuf(f, path)?;
writeln!(f, )
writeln!(f,)
}
fn unknown_type<W: Write>(&self, f: &mut W, path: &PathBuf) -> io::Result<()> {
write!(f, "# Failed to detect mime type for ")?;
write_pathbuf(f, path)?;
writeln!(f, )
writeln!(f,)
}
fn header<W: Write>(&self, _: &Entries, f: &mut W) -> io::Result<()> {
write!(f, "#!/usr/bin/env sh\n\nGenerated by fif {}.\n\n", VERSION.unwrap_or("???"))
write!(
f,
"#!/usr/bin/env sh\n\nGenerated by fif {}.\n\n",
VERSION.unwrap_or("???")
)
}
fn footer<W: Write>(&self, _: &Entries, f: &mut W) -> io::Result<()> {

View file

@ -21,7 +21,7 @@ use crate::mimedb::MimeDb;
// at least 265 bytes to identify a tar file.
const BUF_SIZE: usize = 512;
pub fn mime_type<T: MimeDb>(db: &T, path: &Path) -> io::Result<Option<Mime>, > {
pub fn mime_type<T: MimeDb>(db: &T, path: &Path) -> io::Result<Option<Mime>> {
// attempt to read up to the BUF_SIZE bytes of the file
let mut buffer = [0; 64];
@ -30,8 +30,7 @@ pub fn mime_type<T: MimeDb>(db: &T, path: &Path) -> io::Result<Option<Mime>, > {
// this lint can be ignored: it's okay if the file isn't long enough to fill the buffer, as we only care about the
// first few bytes for the purpose of mime sniffing
#[allow(clippy::unused_io_amount)]
file.read(&mut buffer)?;
file.read(&mut buffer)?;
let r = db.get_type(&buffer);
if r.is_some() {
@ -61,4 +60,3 @@ cached! {
}
}
}

View file

@ -21,7 +21,7 @@ use clap::Clap;
use log::{debug, info, trace, warn};
use once_cell::sync::OnceCell;
#[cfg(feature = "multi-threaded")]
use rayon::prelude::*;
use rayon::prelude::*;
use smartstring::alias::String;
use walkdir::{DirEntry, WalkDir};
@ -31,18 +31,18 @@ use crate::mimedb::MimeDb;
use crate::parameters::OutputFormat;
use crate::scanerror::ScanError;
mod parameters;
mod inspectors;
mod formats;
mod scanerror;
mod findings;
mod formats;
mod inspectors;
mod mimedb;
mod parameters;
mod scanerror;
#[cfg(feature = "infer-backend")]
static MIMEDB: OnceCell<mimedb::InferDb> = OnceCell::new();
static MIMEDB: OnceCell<mimedb::InferDb> = OnceCell::new();
#[cfg(feature = "xdg-mime-backend")]
static MIMEDB: OnceCell<mimedb::XdgDb> = OnceCell::new();
static MIMEDB: OnceCell<mimedb::XdgDb> = OnceCell::new();
// TODO: test if this actually works on a windows machine
#[cfg(windows)]
@ -50,14 +50,17 @@ fn is_hidden(entry: &DirEntry) -> bool {
use std::os::windows::prelude::*;
std::fs::metadata(entry) // try to get metadata for file
.map_or(
false, // if getting metadata/attributes fails, assume it's not hidden
false, // if getting metadata/attributes fails, assume it's not hidden
|f| f.file_attributes() & 0x2 > 0, // flag for hidden - https://docs.microsoft.com/windows/win32/fileio/file-attribute-constants
)
}
#[cfg(not(windows))]
fn is_hidden(entry: &DirEntry) -> bool {
entry.file_name().to_str().map_or(false, |f| f.starts_with('.') && f != ".")
entry
.file_name()
.to_str()
.map_or(false, |f| f.starts_with('.') && f != ".")
}
fn wanted_file(args: &parameters::Parameters, entry: &DirEntry) -> bool {
@ -73,7 +76,9 @@ fn wanted_file(args: &parameters::Parameters, entry: &DirEntry) -> bool {
let ext = extension_from_path(entry.path());
if ext.is_none() { return false; } // don't scan files without extensions. TODO - this should be configurable
if ext.is_none() {
return false;
} // don't scan files without extensions. TODO - this should be configurable
if let Some(extensions) = &args.extensions {
// if the user has specified a list of extensions to check against, make sure this file ends in one of them.
@ -117,7 +122,7 @@ fn scan_file(entry: &DirEntry) -> Result<Findings, (ScanError, PathBuf)> {
// there is a known set of extensions for this mimetype, but the file has no extension
Some(_) => false,
// there is no known set of extensions for this mimetype -- assume it's correct
None => true
None => true,
};
Ok(Findings {
@ -128,25 +133,25 @@ fn scan_file(entry: &DirEntry) -> Result<Findings, (ScanError, PathBuf)> {
}
fn scan_from_walkdir(entries: Vec<DirEntry>) -> Vec<Result<Findings, (ScanError, PathBuf)>> {
#[cfg(feature = "multi-threaded")] {
#[cfg(feature = "multi-threaded")]
{
// rather than using a standard par_iter, split the entries into chunks of 32 first.
// this allows each spawned thread to handle 32 files before before closing, rather than creating a new thread for
// each file. this leads to a pretty substantial speedup that i'm pretty substantially happy about 0u0
entries
.par_chunks(32) // split into chunks of 32
.flat_map(|chunk| chunk // return Vec<...> instead of Chunk<Vec<...>>
.iter() // iter over the chunk, which is a slice of DirEntry structs
.map(|entry| scan_file(entry))
.collect::<Vec<_>>()
)
.flat_map(|chunk| {
chunk // return Vec<...> instead of Chunk<Vec<...>>
.iter() // iter over the chunk, which is a slice of DirEntry structs
.map(|entry| scan_file(entry))
.collect::<Vec<_>>()
})
.collect()
}
#[cfg(not(feature = "multi-threaded"))] {
entries
.iter()
.map(|entry: &DirEntry| scan_file(entry))
.collect()
#[cfg(not(feature = "multi-threaded"))]
{
entries.iter().map(|entry: &DirEntry| scan_file(entry)).collect()
}
}
@ -161,10 +166,16 @@ fn main() {
.init();
#[cfg(feature = "infer-backend")]
MIMEDB.set(mimedb::InferDb::init()).or(Err("Failed to initialise MIMEDB")).unwrap();
MIMEDB
.set(mimedb::InferDb::init())
.or(Err("Failed to initialise MIMEDB"))
.unwrap();
#[cfg(feature = "xdg-mime-backend")]
MIMEDB.set(mimedb::XdgDb::init()).or(Err("Failed to initialise MIMEDB")).unwrap();
MIMEDB
.set(mimedb::XdgDb::init())
.or(Err("Failed to initialise MIMEDB"))
.unwrap();
debug!("Iterating directory: {:?}", args.dirs);
@ -183,21 +194,26 @@ fn main() {
match result {
Ok(r) => {
if !r.valid {
info!("{:?} should have file extension {}", r.file, r.recommended_extension().unwrap())
info!(
"{:?} should have file extension {}",
r.file,
r.recommended_extension().unwrap()
)
} else {
trace!("{:?} is totally fine", r.file)
}
}
Err(f) => warn!("{:#?}: Error 0uo - {}", f.1, f.0)
Err(f) => warn!("{:#?}: Error 0uo - {}", f.1, f.0),
}
}
match args.output_format {
OutputFormat::Script => {
let s = Script::new();
s.write_all(&results, &mut BufWriter::new(stdout().lock())).expect("failed to output");
s.write_all(&results, &mut BufWriter::new(stdout().lock()))
.expect("failed to output");
}
OutputFormat::Text => todo!()
OutputFormat::Text => todo!(),
}
debug!("Done");

View file

@ -1,6 +1,7 @@
use mime_guess::Mime;
#[cfg(feature = "infer-backend")]
use std::str::FromStr;
use std::str::FromStr;
use mime_guess::Mime;
pub trait MimeDb {
fn init() -> Self;
@ -9,7 +10,7 @@ pub trait MimeDb {
#[cfg(feature = "infer-backend")]
pub struct InferDb {
db: infer::Infer
db: infer::Infer,
}
#[cfg(feature = "infer-backend")]
@ -17,11 +18,8 @@ impl MimeDb for InferDb {
fn init() -> Self {
let mut info = infer::Infer::new();
// add a random file type just to make sure adding works and such
info.add(
"image/jpeg2000",
".jp2",
|buf| {
buf.len() > 23
info.add("image/jpeg2000", ".jp2", |buf| {
buf.len() > 23
&& buf[0] == 0x00
&& buf[1] == 0x00
&& buf[2] == 0x00
@ -38,8 +36,7 @@ impl MimeDb for InferDb {
&& buf[21] == 0x70
&& buf[22] == 0x32
&& buf[23] == 0x20
}
);
});
// unmut
let info = info;
@ -48,22 +45,20 @@ impl MimeDb for InferDb {
}
fn get_type(&self, data: &[u8]) -> Option<Mime> {
self.db
.get(data)
.map(|f| Mime::from_str(f.mime_type()).unwrap())
self.db.get(data).map(|f| Mime::from_str(f.mime_type()).unwrap())
}
}
#[cfg(feature = "xdg-mime-backend")]
pub struct XdgDb {
db: xdg_mime::SharedMimeInfo
db: xdg_mime::SharedMimeInfo,
}
#[cfg(feature = "xdg-mime-backend")]
impl MimeDb for XdgDb {
fn init() -> Self {
Self {
db: xdg_mime::SharedMimeInfo::new()
db: xdg_mime::SharedMimeInfo::new(),
}
}

View file

@ -2,16 +2,18 @@ use std::fmt::{Display, Formatter, Result};
pub enum ScanError {
File,
Mime
Mime,
}
impl Display for ScanError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}",
match self {
Self::File => "Couldn't read file",
Self::Mime => "Couldn't determine mime type"
}
write!(
f,
"{}",
match self {
Self::File => "Couldn't read file",
Self::Mime => "Couldn't determine mime type",
}
)
}
}