working ver

rust
Avril 4 years ago
parent 1f34da16cb
commit 0b141f9ee3
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -7,3 +7,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
memmap = "0.7.0"
rayon = "1.5.0"
smallvec = "1.5.0"

@ -0,0 +1,20 @@
pub trait ResultPrintExt<T>
{
fn discard_msg(self, msg: impl AsRef<str>) -> Option<T>;
}
impl<T, E> ResultPrintExt<T> for Result<T,E>
where E: std::fmt::Display
{
fn discard_msg(self, msg: impl AsRef<str>) -> Option<T> {
match self {
Ok(v) => Some(v),
Err(e) => {
eprintln!("{}: {}", msg.as_ref(), e);
None
},
}
}
}

@ -1,3 +1,61 @@
use rayon::prelude::*;
use std::{
path::Path,
io, fs::{self, OpenOptions,},
};
use smallvec::SmallVec;
fn usage() -> !
{
eprintln!("fcmprs: Compare files for identity");
eprintln!("Usage: {} <files...>", std::env::args().next().unwrap());
std::process::exit(-1)
}
mod error;
use error::ResultPrintExt as _;
mod map;
fn main() {
println!("Hello, world!");
let (map1, rest) = {
let mut args = std::env::args().skip(1);
if let Some(one) = args.next() {
(one, args)
} else {
usage();
}
};
std::process::exit(dbg!(if let Some(map1) = map::map(&map1).discard_msg(format!("Failed to map file {}", map1)) {
let slice = map1.as_slice();
let mut ok = true;
let chk: SmallVec<[_; 32]> = rest.filter_map(|filename| {
let path = Path::new(&filename);
if path.exists() && path.is_file() {
map::map(path).discard_msg(format!("Failed to map file {}", filename))
.or_else(|| { ok = false; None })
} else {
eprintln!("File {} does not exist or is not a normal file", filename);
ok = false;
None
}
}).collect();
if !ok {
-1
} else {
match chk.into_par_iter()
.map(|map| slice == map.as_slice())
.reduce_with(|x, y| x && y)
{
Some(true) => 0,
Some(false) => 1,
None => usage(),
}
}
} else {
-1
}))
}

@ -0,0 +1,30 @@
use super::*;
/// Represents an open and memory mapped file
#[derive(Debug)]
pub struct MemMap
{
map: memmap::Mmap,
file: fs::File,
}
impl MemMap
{
/// Get the memory mapped portion as a slice
#[inline] pub fn as_slice(&self) -> &[u8]
{
&self.map[..]
}
}
/// Attempt to map this file
pub fn map(file: impl AsRef<Path>) -> io::Result<MemMap>
{
let file = OpenOptions::new()
.read(true)
.open(file)?;
Ok(MemMap {
map: unsafe { memmap::Mmap::map(&file)? },
file,
})
}
Loading…
Cancel
Save