nicer formatting, moved Findings into its own file
This commit is contained in:
parent
3642f0112a
commit
d7eb0de299
8 changed files with 48 additions and 39 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -176,6 +176,7 @@ dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
|
"once_cell",
|
||||||
"rayon",
|
"rayon",
|
||||||
"smartstring",
|
"smartstring",
|
||||||
"snailquote",
|
"snailquote",
|
||||||
|
|
|
@ -23,6 +23,7 @@ xdg-mime = {git = "https://github.com/ebassi/xdg-mime-rs", version = "0.3", rev
|
||||||
mime_guess = "2.0.3"
|
mime_guess = "2.0.3"
|
||||||
rayon = "1.5.0"
|
rayon = "1.5.0"
|
||||||
snailquote = "0.3.0"
|
snailquote = "0.3.0"
|
||||||
|
once_cell = "1.5.2"
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
version = "3.0.0-beta.2"
|
version = "3.0.0-beta.2"
|
||||||
|
|
17
src/findings.rs
Normal file
17
src/findings.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use crate::inspectors::mime_extension_lookup;
|
||||||
|
use mime_guess::Mime;
|
||||||
|
use smartstring::alias::String;
|
||||||
|
|
||||||
|
pub struct Findings {
|
||||||
|
pub file: PathBuf, // TODO: replace with Path???? <'a> and all that
|
||||||
|
pub valid: bool,
|
||||||
|
pub mime: Mime,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Findings {
|
||||||
|
pub fn recommended_extension(&self) -> Option<String> {
|
||||||
|
mime_extension_lookup(self.mime.clone())
|
||||||
|
.map(|extensions| extensions[0].to_owned())
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,13 +16,13 @@ type Entries = [Result<Findings, (ScanError, PathBuf)>];
|
||||||
|
|
||||||
fn write_pathbuf<W: Write>(f: &mut W, path: &PathBuf) -> io::Result<()> {
|
fn write_pathbuf<W: Write>(f: &mut W, path: &PathBuf) -> io::Result<()> {
|
||||||
match path.to_str() {
|
match path.to_str() {
|
||||||
Some(string) => {write!(f, "{}", escape(string))}
|
Some(string) => { write!(f, "{}", escape(string)) }
|
||||||
None => {
|
None => {
|
||||||
write!(f, "'")?;
|
write!(f, "'")?;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
f.write_all(&*path.as_os_str().as_bytes())?;
|
f.write_all(&*path.as_os_str().as_bytes())?;
|
||||||
#[cfg(windows)]
|
#[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, "'")
|
write!(f, "'")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,9 +51,8 @@ pub trait Format {
|
||||||
self.rename(
|
self.rename(
|
||||||
f,
|
f,
|
||||||
&finding.file,
|
&finding.file,
|
||||||
&finding.file.with_extension(ext.as_str())
|
&finding.file.with_extension(ext.as_str()),
|
||||||
)?
|
)?
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
self.no_known_extension(f, &finding.file)?
|
self.no_known_extension(f, &finding.file)?
|
||||||
}
|
}
|
||||||
|
@ -76,6 +75,7 @@ pub trait Format {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Script {}
|
pub struct Script {}
|
||||||
|
|
||||||
impl Format for Script {
|
impl Format for Script {
|
||||||
fn new() -> Self { Self {} }
|
fn new() -> Self { Self {} }
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn mime_type(db: &SharedMimeInfo, 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
|
// 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
|
// first few bytes for the purpose of mime sniffing
|
||||||
#[allow(clippy::unused_io_amount)]
|
#[allow(clippy::unused_io_amount)]
|
||||||
file.read(&mut buffer)?;
|
file.read(&mut buffer)?;
|
||||||
|
|
||||||
|
|
||||||
let r = db.get_mime_type_for_data(&buffer).map(|m| m.0);
|
let r = db.get_mime_type_for_data(&buffer).map(|m| m.0);
|
||||||
|
|
39
src/main.rs
39
src/main.rs
|
@ -20,7 +20,6 @@ use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use clap::Clap;
|
use clap::Clap;
|
||||||
use log::{debug, info, trace, warn};
|
use log::{debug, info, trace, warn};
|
||||||
use mime_guess::Mime;
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use smartstring::alias::String;
|
use smartstring::alias::String;
|
||||||
use walkdir::{DirEntry, WalkDir};
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
@ -29,35 +28,13 @@ use xdg_mime::SharedMimeInfo;
|
||||||
use crate::formats::{Format, Script};
|
use crate::formats::{Format, Script};
|
||||||
use crate::parameters::OutputFormat;
|
use crate::parameters::OutputFormat;
|
||||||
use crate::scanerror::ScanError;
|
use crate::scanerror::ScanError;
|
||||||
|
use crate::findings::Findings;
|
||||||
|
|
||||||
mod parameters;
|
mod parameters;
|
||||||
mod inspectors;
|
mod inspectors;
|
||||||
mod formats;
|
mod formats;
|
||||||
mod scanerror;
|
mod scanerror;
|
||||||
|
mod findings;
|
||||||
pub struct Findings {
|
|
||||||
file: PathBuf, // TODO: replace with Path???? <'a> and all that
|
|
||||||
valid: bool,
|
|
||||||
mime: Mime,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Findings {
|
|
||||||
fn recommended_extension(&self) -> Option<String> {
|
|
||||||
inspectors::mime_extension_lookup(self.mime.clone())
|
|
||||||
.map(|extensions| extensions[0].to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for ScanError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "{}",
|
|
||||||
match self {
|
|
||||||
Self::File => "Couldn't read file",
|
|
||||||
Self::Mime => "Couldn't determine mime type"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: test if this actually works on a windows machine - not there's much of a point right now, considering
|
// TODO: test if this actually works on a windows machine - not there's much of a point right now, considering
|
||||||
// xdg-mime-rs doesn't support windows
|
// xdg-mime-rs doesn't support windows
|
||||||
|
@ -67,7 +44,7 @@ fn is_hidden(entry: &DirEntry) -> bool {
|
||||||
std::fs::metadata(entry) // try to get metadata for file
|
std::fs::metadata(entry) // try to get metadata for file
|
||||||
.map_or(
|
.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
|
|f| f.file_attributes() & 0x2 > 0, // flag for hidden - https://docs.microsoft.com/windows/win32/fileio/file-attribute-constants
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,11 +66,11 @@ fn wanted_file(args: ¶meters::Parameters, entry: &DirEntry) -> bool {
|
||||||
|
|
||||||
let ext = extension_from_path(entry.path());
|
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 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.
|
// if the user has specified a list of extensions to check against, make sure this file ends in one of them.
|
||||||
return extensions.contains(&ext.unwrap().to_lowercase().into())
|
return extensions.contains(&ext.unwrap().to_lowercase().into());
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -161,7 +138,7 @@ fn scan_from_walkdir(db: &SharedMimeInfo, entries: Vec<DirEntry>) -> Vec<Result<
|
||||||
#[cfg(not(feature = "multi-threaded"))] {
|
#[cfg(not(feature = "multi-threaded"))] {
|
||||||
entries
|
entries
|
||||||
.iter()
|
.iter()
|
||||||
.map(|entry: &DirEntry | scan_file(db, entry))
|
.map(|entry: &DirEntry| scan_file(db, entry))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,10 +181,10 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
match args.output_format {
|
match args.output_format {
|
||||||
OutputFormat::Script => {
|
OutputFormat::Script => {
|
||||||
let s = Script::new();
|
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 => debug!("eewr")
|
OutputFormat::Text => debug!("eewr")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use smartstring::{LazyCompact, SmartString};
|
||||||
#[derive(Clap, PartialEq, Debug)]
|
#[derive(Clap, PartialEq, Debug)]
|
||||||
pub enum OutputFormat {
|
pub enum OutputFormat {
|
||||||
Script,
|
Script,
|
||||||
Text
|
Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clap, Debug)]
|
#[derive(Clap, Debug)]
|
||||||
|
@ -20,7 +20,7 @@ pub struct Parameters {
|
||||||
pub scan_hidden: bool,
|
pub scan_hidden: bool,
|
||||||
|
|
||||||
/// Output format to use. See "--help formats" for more information.
|
/// Output format to use. See "--help formats" for more information.
|
||||||
#[clap(short, long, default_value="script", arg_enum)]
|
#[clap(short, long, default_value = "script", arg_enum)]
|
||||||
pub output_format: OutputFormat,
|
pub output_format: OutputFormat,
|
||||||
|
|
||||||
/// Directory to process
|
/// Directory to process
|
||||||
|
|
|
@ -1,4 +1,17 @@
|
||||||
|
use std::fmt::{Display, Formatter, Result};
|
||||||
|
|
||||||
pub enum ScanError {
|
pub enum ScanError {
|
||||||
File,
|
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"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue