lla 0.1.6

A lightweight ls replacement
use crate::error::LlaError;
use std::fs::Metadata;
use std::path::PathBuf;

pub struct AlphabeticalSorter;
pub struct SizeSorter;
pub struct DateSorter;

pub trait FileSorter {
    fn sort_files(&self, files: Vec<PathBuf>) -> Vec<PathBuf>;
}

impl AlphabeticalSorter {
    pub fn new() -> AlphabeticalSorter {
        AlphabeticalSorter {}
    }
}

impl FileSorter for AlphabeticalSorter {
    fn sort_files(&self, mut files: Vec<PathBuf>) -> Vec<PathBuf> {
        files.sort();
        files
    }
}

impl SizeSorter {
    pub fn new() -> SizeSorter {
        SizeSorter {}
    }

    fn get_file_size(&self, file: &PathBuf) -> Option<u64> {
        if let Ok(metadata) = file.metadata() {
            Some(metadata.len())
        } else {
            None
        }
    }
}

impl FileSorter for SizeSorter {
    fn sort_files(&self, mut files: Vec<PathBuf>) -> Vec<PathBuf> {
        files.sort_by(|a, b| {
            let size_a = self.get_file_size(a).unwrap_or(u64::MAX);
            let size_b = self.get_file_size(b).unwrap_or(u64::MAX);
            size_a.cmp(&size_b)
        });
        files
    }
}

impl DateSorter {
    pub fn new() -> DateSorter {
        DateSorter {}
    }

    fn get_modification_date(&self, file: &PathBuf) -> Option<Metadata> {
        if let Ok(metadata) = file.metadata() {
            Some(metadata)
        } else {
            None
        }
    }
}

impl FileSorter for DateSorter {
    fn sort_files(&self, mut files: Vec<PathBuf>) -> Vec<PathBuf> {
        files.sort_by(|a, b| {
            let date_a = self
                .get_modification_date(a)
                .ok_or_else(|| LlaError::FailedToGetMetadata(a.to_string_lossy().to_string()));
            let date_b = self
                .get_modification_date(b)
                .ok_or_else(|| LlaError::FailedToGetMetadata(b.to_string_lossy().to_string()));
            date_a
                .map_err(|e| eprintln!("{}", e))
                .unwrap_or_else(|_| std::process::exit(1))
                .modified()
                .map_err(|e| eprintln!("{}", e))
                .unwrap_or_else(|_| std::process::exit(1))
                .cmp(&date_b.unwrap().modified().unwrap())
        });

        files
    }
}