#![cfg_attr(test, deny(warnings))]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![allow(clippy::must_use_candidate)]
#![deny(
future_incompatible,
missing_debug_implementations,
missing_docs,
missing_copy_implementations,
missing_docs,
nonstandard_style,
trivial_casts,
trivial_numeric_casts,
unsafe_code,
unused_extern_crates,
unused_import_braces,
unused_qualifications,
unused_results,
unused_qualifications
)]
pub mod commands;
pub(crate) mod config;
mod errors;
pub mod paths;
pub use crate::config::Config;
pub use crate::errors::InputError;
#[macro_use] extern crate failure;
use std::fs::{self, File};
use std::io::{self, prelude::*, BufWriter};
use std::path::{Path, PathBuf};
#[derive(Debug)]
pub struct DirScanner {
entries: Vec<PathBuf>,
recursive: bool,
}
impl DirScanner {
pub fn get_entries(mut self, dir: &Path) -> io::Result<Vec<PathBuf>> {
self.collect_entries(dir)?;
self.entries = self
.entries
.into_iter()
.map(|path| {
if path.is_relative() {
fs::canonicalize(path)
} else {
Ok(path)
}
})
.filter_map(Result::ok)
.collect();
Ok(self.entries)
}
pub fn recursive(mut self) -> Self {
self.recursive = true;
self
}
fn collect_entries(&mut self, dir: &Path) -> io::Result<()> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let path = entry.map(|e| e.path())?;
if path.is_dir() && self.recursive {
if !path.ends_with(".git") {
self.collect_entries(&path)?;
}
} else {
self.entries.push(path)
}
}
}
Ok(())
}
}
impl Default for DirScanner {
fn default() -> Self {
Self {
entries: vec![],
recursive: false,
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct FileHandler;
impl FileHandler {
pub fn store_file(src: &Path, dst: &Path) -> io::Result<()> {
Self::move_file(src, dst)?;
Self::create_symlink(dst, src)
}
pub fn move_file(src: &Path, dst: &Path) -> io::Result<()> {
let contents = crate::paths::read_path(src)?;
let dst_file = File::create(dst)?;
let mut writer = BufWriter::new(dst_file);
writer.write_all(contents.as_bytes())?;
fs::remove_file(&src)
}
pub fn create_symlink(src: &Path, dst: &Path) -> io::Result<()> {
#[cfg(not(target_os = "windows"))] use std::os::unix::fs::symlink;
#[cfg(target_os = "windows")]
use std::os::windows::fs::symlink_file as symlink;
symlink(src, dst)
}
}