1
0
Fork 0
mirror of https://github.com/nachoparker/dutree synced 2024-05-12 23:56:08 +02:00

Split dictionaries into an external crate

This commit is contained in:
nacho 2018-04-16 14:36:08 +02:00
parent 5a1f1f7f51
commit deba1dfcc6
4 changed files with 68 additions and 57 deletions

9
Cargo.lock generated
View File

@ -6,10 +6,16 @@ dependencies = [
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "dict"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "dutree" name = "dutree"
version = "0.1.0" version = "0.2.0"
dependencies = [ dependencies = [
"dict 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"terminal_size 0.1.7 (git+https://github.com/eminence/terminal-size.git)", "terminal_size 0.1.7 (git+https://github.com/eminence/terminal-size.git)",
@ -127,6 +133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata] [metadata]
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
"checksum dict 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7799ea4aadf97b4236e761799371f7ba10ea6327c69bd51690dd567bf0ae539"
"checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"

View File

@ -1,9 +1,10 @@
[package] [package]
name = "dutree" name = "dutree"
version = "0.1.0" version = "0.2.1"
authors = ["nacho <nacho.nunez@aoifes.com>"] authors = ["nacho <nacho@ownyourbits.com>"]
[dependencies] [dependencies]
dict = "0.1.1"
getopts = "0.2" getopts = "0.2"
terminal_size= { git = "https://github.com/eminence/terminal-size.git" } terminal_size= { git = "https://github.com/eminence/terminal-size.git" }
regex = "0.2" regex = "0.2"

View File

@ -24,6 +24,7 @@ Options:
-s, --summary equivalent to -da, or -d1 -a1M -s, --summary equivalent to -da, or -d1 -a1M
-u, --usage report real disk usage instead of file size -u, --usage report real disk usage instead of file size
-b, --bytes print sizes in bytes -b, --bytes print sizes in bytes
-f, --files-only skip directories for a fast local overview
-x, --exclude NAME exclude matching files or directories -x, --exclude NAME exclude matching files or directories
-H, --no-hidden exclude hidden files -H, --no-hidden exclude hidden files
-A, --ascii ASCII characters only, no colors -A, --ascii ASCII characters only, no colors

View File

@ -30,17 +30,24 @@
/// ///
/// More at https://ownyourbits.com /// More at https://ownyourbits.com
/// ///
extern crate getopts;
extern crate terminal_size;
extern crate regex;
extern crate unicode_width; extern crate unicode_width;
extern crate getopts;
use getopts::Options; use getopts::Options;
extern crate terminal_size;
use terminal_size::{Width, Height, terminal_size};
extern crate regex;
use regex::Regex;
extern crate dict;
use dict::{ Dict, DictIface };
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::fs; use std::fs;
use terminal_size::{Width, Height, terminal_size};
use regex::Regex;
use std::os::linux::fs::MetadataExt; use std::os::linux::fs::MetadataExt;
use std::env; use std::env;
@ -57,14 +64,14 @@ use XResult::{XOk, XExit, XErr};
struct Entry { struct Entry {
name : String, name : String,
bytes : u64, bytes : u64,
color : Option<String>, color : Option<String>, // TODO reference
last : bool, last : bool,
entries : Option<Vec<Entry>>, entries : Option<Vec<Entry>>,
} }
pub struct Config { pub struct Config {
paths : Vec<PathBuf>, paths : Vec<PathBuf>,
color_dict : Vec<DictEntry>, color_dict : Dict<String>,
depth : u8, depth : u8,
depth_flag : bool, depth_flag : bool,
bytes_flag : bool, bytes_flag : bool,
@ -76,22 +83,22 @@ pub struct Config {
exclude : Vec<String>, exclude : Vec<String>,
} }
struct DictEntry { key : String, val : String } //struct DictEntry { key : String, val : String }
fn init_opts() -> Options { fn init_opts() -> Options {
let mut options = Options::new(); let mut options = Options::new();
options.optflagopt( "d", "depth" , "show directories up to depth N (def 1)", "DEPTH" ); options.optflagopt( "d", "depth" , "show directories up to depth N (def 1)", "DEPTH" );
options.optflagopt( "a", "aggr" , "aggregate smaller than N B/KiB/MiB/GiB (def 1M)", "N[KMG]"); options.optflagopt( "a", "aggr" , "aggregate smaller than N B/KiB/MiB/GiB (def 1M)", "N[KMG]");
options.optflag( "s", "summary" , "equivalent to -da, or -d1 -a1M" ); options.optflag( "s", "summary" , "equivalent to -da, or -d1 -a1M" );
options.optflag( "u", "usage" , "report real disk usage instead of file size"); options.optflag( "u", "usage" , "report real disk usage instead of file size" );
options.optflag( "b", "bytes" , "print sizes in bytes" ); options.optflag( "b", "bytes" , "print sizes in bytes" );
options.optflag( "f", "files-only","skip directories for a fast local overview" ); options.optflag( "f", "files-only","skip directories for a fast local overview" );
options.optmulti( "x", "exclude" , "exclude matching files or directories", "NAME"); options.optmulti( "x", "exclude" , "exclude matching files or directories", "NAME" );
options.optflag( "H", "no-hidden", "exclude hidden files" ); options.optflag( "H", "no-hidden", "exclude hidden files" );
options.optflag( "A", "ascii" , "ASCII characters only, no colors" ); options.optflag( "A", "ascii" , "ASCII characters only, no colors" );
options.optflag( "h", "help" , "show help" ); options.optflag( "h", "help" , "show help" );
options.optflag( "v", "version" , "print version number" ); options.optflag( "v", "version" , "print version number" );
options options
} }
@ -301,7 +308,11 @@ impl Entry {
}; };
// calculate color // calculate color
let color = if !cfg.ascii_flag {color_from_path(path, &cfg.color_dict)} else {None}; let color = if !cfg.ascii_flag {
if let Some( col ) = color_from_path(path, &cfg.color_dict) {
Some( col.to_string() ) // TODO use references
} else { None }
} else { None };
Entry { name, bytes, color, last: false, entries } Entry { name, bytes, color, last: false, entries }
} }
@ -445,15 +456,15 @@ fn get_bytes( path: &Path, usage_flag : bool ) -> u64 {
} }
} }
fn color_from_path( path : &Path, color_dict : &Vec<DictEntry> ) -> Option<String> { fn color_from_path<'a>( path : &Path, color_dict : &'a Dict<String> ) -> Option<&'a str> {
if try_is_symlink( path ) { if try_is_symlink( path ) {
if path.read_link().unwrap().exists() { if path.read_link().unwrap().exists() {
if let Some( col ) = dict_get( color_dict, "ln" ) { if let Some( col ) = color_dict.get( "ln" ) {
return Some( col.to_string() ); return Some( &col );
} }
} else { } else {
if let Some( col ) = dict_get( color_dict, "or" ) { if let Some( col ) = color_dict.get( "or" ) {
return Some( col.to_string() ); return Some( &col );
} }
} }
} }
@ -462,17 +473,17 @@ fn color_from_path( path : &Path, color_dict : &Vec<DictEntry> ) -> Option<Strin
let mode = metadata.unwrap().st_mode(); let mode = metadata.unwrap().st_mode();
if path.is_dir() { if path.is_dir() {
if mode & 0o002 != 0 { // dir other writable if mode & 0o002 != 0 { // dir other writable
if let Some( col ) = dict_get( color_dict, "ow" ) { if let Some( col ) = color_dict.get( "ow" ) {
return Some( col.to_string() ); return Some( &col );
} }
} }
if let Some( col ) = dict_get( color_dict, "di" ) { if let Some( col ) = color_dict.get( "di" ) {
return Some( col.to_string() ); return Some( &col );
} }
} }
if mode & 0o111 != 0 { // executable if mode & 0o111 != 0 { // executable
if let Some( col ) = dict_get( color_dict, "ex" ) { if let Some( col ) = color_dict.get( "ex" ) {
return Some( col.to_string() ); return Some( &col );
} }
} }
} }
@ -481,19 +492,19 @@ fn color_from_path( path : &Path, color_dict : &Vec<DictEntry> ) -> Option<Strin
if &col.key[..2] != "*." { continue } if &col.key[..2] != "*." { continue }
let key = col.key.trim_left_matches( "*." ); let key = col.key.trim_left_matches( "*." );
if ext_str == key { if ext_str == key {
return Some( dict_get( color_dict, col.key.as_str() ).unwrap().to_string() ); return Some( &color_dict.get( col.key.as_str() ).unwrap() );
} }
} }
} }
if path.is_file() { if path.is_file() {
if let Some( col ) = dict_get( color_dict, "fi" ) { if let Some( col ) = color_dict.get( "fi" ) {
return Some( col.to_string() ); return Some( &col );
} }
else { return None } else { return None }
} }
// we are assuming it can only be a 'bd','cd'. can also be 'pi','so' or 'no' // we are assuming it can only be a 'bd','cd'. can also be 'pi','so' or 'no'
if let Some( col ) = dict_get( color_dict, "bd" ) { if let Some( col ) = color_dict.get( "bd" ) {
return Some( col.to_string() ); return Some( &col );
} }
None None
} }
@ -503,17 +514,8 @@ fn print_usage( program: &str, opts: &Options ) {
print!( "{}", opts.usage( &brief ) ); print!( "{}", opts.usage( &brief ) );
} }
fn dict_get( dict : &Vec<DictEntry>, key : &str ) -> Option<String> { fn create_color_dict() -> Dict<String> {
for entry in dict { let mut color_dict = Dict::<String>::new();
if &entry.key == key {
return Some( entry.val.clone() );
}
}
None
}
fn create_color_dict() -> Vec<DictEntry> {
let mut color_dict = Vec::new();
let env_str = env::var("LS_COLORS").unwrap_or( "".to_string() ); let env_str = env::var("LS_COLORS").unwrap_or( "".to_string() );
for entry in env_str.split(':') { for entry in env_str.split(':') {
if entry.len() == 0 { break; } if entry.len() == 0 { break; }
@ -523,7 +525,7 @@ fn create_color_dict() -> Vec<DictEntry> {
let key = line.next().unwrap(); let key = line.next().unwrap();
let val = line.next().unwrap(); let val = line.next().unwrap();
color_dict.push( DictEntry{ key: key.to_string(), val: val.to_string() } ); color_dict.add( key.to_string(), val.to_string() );
} }
color_dict color_dict
} }
@ -562,14 +564,14 @@ mod tests {
#[test] #[test]
fn parse_ls_colors() { fn parse_ls_colors() {
let mut dict = Vec::new(); let mut dict_ = Vec::new();
dict.push( DictEntry{ key: "di".to_string() , val: "dircode".to_string() } ); dict_.push( DictEntry{ key: "di".to_string() , val: "dircode".to_string() } );
dict.push( DictEntry{ key: "li".to_string() , val: "linkcod".to_string() } ); dict_.push( DictEntry{ key: "li".to_string() , val: "linkcod".to_string() } );
dict.push( DictEntry{ key: "*.mp3".to_string(), val: "mp3code".to_string() } ); dict_.push( DictEntry{ key: "*.mp3".to_string(), val: "mp3code".to_string() } );
dict.push( DictEntry{ key: "*.tar".to_string(), val: "tarcode".to_string() } ); dict_.push( DictEntry{ key: "*.tar".to_string(), val: "tarcode".to_string() } );
assert_eq!( "dircode", color_from_path( Path::new(".") , &dict ) ); assert_eq!( "dircode", color_from_path( Path::new(".") , &dict_ ) );
assert_eq!( "mp3code", color_from_path( Path::new("test.mp3"), &dict ) ); assert_eq!( "mp3code", color_from_path( Path::new("test.mp3"), &dict_ ) );
assert_eq!( "tarcode", color_from_path( Path::new("test.tar"), &dict ) ); assert_eq!( "tarcode", color_from_path( Path::new("test.tar"), &dict_ ) );
} }
/* /*