parent
8434cf0425
commit
a68f418ffd
@ -0,0 +1,18 @@
|
||||
//! Argument stuff
|
||||
use super::*;
|
||||
|
||||
|
||||
/// Name of executable
|
||||
pub fn program_name() -> &'static str
|
||||
{
|
||||
lazy_static! {
|
||||
static ref NAME: String = std::env::args().next().unwrap();
|
||||
}
|
||||
&NAME[..]
|
||||
}
|
||||
|
||||
/// Print usage
|
||||
pub fn usage()
|
||||
{
|
||||
println!(r#"Usage: {} <files...>"#, program_name());
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
use super::*;
|
||||
use std::iter;
|
||||
|
||||
pub trait StringJoinExt: Sized
|
||||
{
|
||||
fn join<P: AsRef<str>>(self, sep: P) -> String;
|
||||
}
|
||||
|
||||
impl<I,T> StringJoinExt for I
|
||||
where I: IntoIterator<Item=T>,
|
||||
T: AsRef<str>
|
||||
{
|
||||
fn join<P: AsRef<str>>(self, sep: P) -> String
|
||||
{
|
||||
let mut string = String::new();
|
||||
for (first, s) in iter::successors(Some(true), |_| Some(false)).zip(self.into_iter())
|
||||
{
|
||||
if !first {
|
||||
string.push_str(sep.as_ref());
|
||||
}
|
||||
string.push_str(s.as_ref());
|
||||
}
|
||||
string
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
//! Map iter
|
||||
use super::*;
|
||||
use std::{
|
||||
iter,
|
||||
collections::HashSet,
|
||||
hash::Hash,
|
||||
};
|
||||
|
||||
//TODO: Feature flag for SHA256 hashing
|
||||
type HashOutput = u64;
|
||||
|
||||
fn compute<H: Hash>(what: &H) -> HashOutput
|
||||
{
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
||||
what.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
pub struct DedupIter<I: Iterator>(I, HashSet<HashOutput>)
|
||||
where <I as Iterator>::Item: Hash;
|
||||
|
||||
impl<I: Iterator> Iterator for DedupIter<I>
|
||||
where I::Item: Hash
|
||||
{
|
||||
type Item = I::Item;
|
||||
fn next(&mut self) -> Option<Self::Item>
|
||||
{
|
||||
if let Some(next) = self.0.next() {
|
||||
let hash = compute(&next);
|
||||
if self.1.insert(hash) {
|
||||
Some(next)
|
||||
} else {
|
||||
return self.next();
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>)
|
||||
{
|
||||
let (low, high) = self.0.size_hint();
|
||||
|
||||
(if low < 1 {0} else {1}, high)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DedupIterExt: Iterator + Sized
|
||||
where Self::Item: Hash
|
||||
{
|
||||
fn dedup(self) -> DedupIter<Self>;
|
||||
}
|
||||
|
||||
impl<I: Iterator> DedupIterExt for I
|
||||
where I::Item: Hash
|
||||
{
|
||||
fn dedup(self) -> DedupIter<Self>
|
||||
{
|
||||
let set = match self.size_hint() {
|
||||
(0, Some(0)) | (0, None) => HashSet::new(),
|
||||
(x, None) | (_, Some(x)) => HashSet::with_capacity(x),
|
||||
};
|
||||
DedupIter(self, set)
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
//! Splash screen~
|
||||
use super::*;
|
||||
use std::borrow::Cow;
|
||||
|
||||
macro_rules! feature {
|
||||
(in $name:tt, $desc:literal) => {
|
||||
cfg_if! {
|
||||
if #[cfg($name)] {
|
||||
println!(" +{}\t{}", stringify!($name), $desc);
|
||||
}
|
||||
}
|
||||
};
|
||||
($name:literal, $desc:literal $($tt:tt)*) => {
|
||||
cfg_if! {
|
||||
if #[cfg(feature=$name)] {
|
||||
println!(" +{}\t{}", $name, format!($desc $($tt)*));
|
||||
} else {
|
||||
println!(" -{}", $name);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn splash() -> ! {
|
||||
arg::usage();
|
||||
|
||||
// splash screen
|
||||
println!(r#"
|
||||
> sever ({}) v{}
|
||||
> Coerce hardlinks to new files
|
||||
|
||||
For verbose output, set `RUST_LOG` env var to one of the following:
|
||||
trace - Most verbose
|
||||
debug - Verbose
|
||||
info - Default
|
||||
warn - Only show warnings
|
||||
error - Only show errors
|
||||
|
||||
Made by {} with <3 (Licensed GPL 3.0 or later)"#, arg::program_name(), env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_AUTHORS"));
|
||||
println!("\nEnabled extensions: ");
|
||||
feature!(in nightly, "\tCompiled with Rust nightly extensions");
|
||||
println!();
|
||||
feature!("parallel", "\tWill run up to {} operations in parallel", parallel::MAX_WORKERS.map(|x| Cow::Owned(x.to_string())).unwrap_or(Cow::Borrowed("unlimited")));
|
||||
feature!("limit-concurrency", "Concurrency is capped");
|
||||
feature!("threads", "\tUsing thread-pool");
|
||||
std::process::exit(1)
|
||||
}
|
Loading…
Reference in new issue