From 933f98d2c3734a69260b6d10ae059130417ae813 Mon Sep 17 00:00:00 2001 From: Ben S Date: Sun, 23 Nov 2014 21:29:11 +0000 Subject: [PATCH] Upgrade to latest Rust nightly --- src/column.rs | 30 +++++++++++++++--------------- src/exa.rs | 17 +++++++++-------- src/file.rs | 34 +++++++++++++++++----------------- src/filetype.rs | 16 ++++++++-------- src/options.rs | 48 +++++++++++++++++++++++++----------------------- src/sort.rs | 13 +++++++------ src/term.rs | 7 +++---- src/unix.rs | 10 +++++----- 8 files changed, 89 insertions(+), 86 deletions(-) diff --git a/src/column.rs b/src/column.rs index 1839275..132497a 100644 --- a/src/column.rs +++ b/src/column.rs @@ -19,24 +19,24 @@ pub enum Alignment { impl Column { pub fn alignment(&self) -> Alignment { match *self { - FileSize(_) => Right, - HardLinks => Right, - Inode => Right, - Blocks => Right, - _ => Left, + Column::FileSize(_) => Alignment::Right, + Column::HardLinks => Alignment::Right, + Column::Inode => Alignment::Right, + Column::Blocks => Alignment::Right, + _ => Alignment::Left, } } pub fn header(&self) -> &'static str { match *self { - Permissions => "Permissions", - FileName => "Name", - FileSize(_) => "Size", - Blocks => "Blocks", - User => "User", - Group => "Group", - HardLinks => "Links", - Inode => "inode", + Column::Permissions => "Permissions", + Column::FileName => "Name", + Column::FileSize(_) => "Size", + Column::Blocks => "Blocks", + Column::User => "User", + Column::Group => "Group", + Column::HardLinks => "Links", + Column::Inode => "inode", } } } @@ -49,8 +49,8 @@ impl Column { impl Alignment { pub fn pad_string(&self, string: &String, padding: uint) -> String { match *self { - Left => string.clone().append(" ".to_string().repeat(padding).as_slice()), - Right => " ".to_string().repeat(padding).append(string.as_slice()), + Alignment::Left => string.clone() + " ".to_string().repeat(padding).as_slice(), + Alignment::Right => " ".to_string().repeat(padding) + string.as_slice(), } } } diff --git a/src/exa.rs b/src/exa.rs index 812c7e1..ccc8b51 100644 --- a/src/exa.rs +++ b/src/exa.rs @@ -1,4 +1,4 @@ -#![feature(phase)] +#![feature(phase, globs)] extern crate regex; #[phase(plugin)] extern crate regex_macros; extern crate ansi_term; @@ -8,8 +8,9 @@ use std::os; use file::File; use dir::Dir; -use column::{Column, Left}; -use options::{Options, Details, Lines, Grid}; +use column::Column; +use column::Alignment::Left; +use options::{Options, View}; use unix::Unix; use ansi_term::{Paint, Plain, strip_formatting}; @@ -25,7 +26,7 @@ pub mod sort; pub mod term; fn main() { - let args = os::args(); + let args: Vec = os::args(); match Options::getopts(args) { Err(err) => println!("Invalid options:\n{}", err), @@ -58,9 +59,9 @@ fn exa(opts: &Options) { } match opts.view { - Details(ref cols) => details_view(opts, cols, files), - Lines => lines_view(files), - Grid(across, width) => grid_view(across, width, files), + View::Details(ref cols) => details_view(opts, cols, files), + View::Lines => lines_view(files), + View::Grid(across, width) => grid_view(across, width, files), } } Err(e) => { @@ -156,7 +157,7 @@ fn details_view(options: &Options, columns: &Vec, files: Vec<&File>) { } else { let padding = column_widths[num] - field_widths[num]; - print!("{}", column.alignment().pad_string(row.get(num), padding)); + print!("{}", column.alignment().pad_string(&row[num], padding)); } } print!("\n"); diff --git a/src/file.rs b/src/file.rs index acaf67b..2bafdd1 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,17 +1,17 @@ use std::io::{fs, IoResult}; use std::io; -use unicode::str::UnicodeStrSlice; use ansi_term::{Paint, Colour, Plain, Style, Red, Green, Yellow, Blue, Purple, Cyan, Fixed}; -use column::{Column, Permissions, FileName, FileSize, User, Group, HardLinks, Inode, Blocks}; +use column::Column; +use column::Column::*; use format::{format_metric_bytes, format_IEC_bytes}; use unix::Unix; use sort::SortPart; use dir::Dir; use filetype::HasType; -static Grey: Colour = Fixed(244); +pub static GREY: Colour = Fixed(244); // Instead of working with Rust's Paths, we have our own File object // that holds the Path and various cached information. Each file is @@ -32,7 +32,7 @@ pub struct File<'a> { impl<'a> File<'a> { pub fn from_path(path: &'a Path, parent: &'a Dir) -> IoResult> { let v = path.filename().unwrap(); // fails if / or . or .. - let filename = String::from_utf8_lossy(v).to_string(); + let filename = String::from_utf8(v.to_vec()).to_string(); // Use lstat here instead of file.stat(), as it doesn't follow // symbolic links. Otherwise, the stat() call will fail if it @@ -129,7 +129,7 @@ impl<'a> File<'a> { Cyan.paint(self.stat.unstable.blocks.to_string().as_slice()) } else { - Grey.paint("-") + GREY.paint("-") } }, @@ -195,7 +195,7 @@ impl<'a> File<'a> { // that reason anyway. match link_target { - Ok(file) => format!("{} {}", Grey.paint("=>"), file.file_colour().paint(filename.as_slice())), + Ok(file) => format!("{} {}", GREY.paint("=>"), file.file_colour().paint(filename.as_slice())), Err(_) => format!("{} {}", Red.paint("=>"), Red.underline().paint(filename.as_slice())), } } @@ -204,7 +204,7 @@ impl<'a> File<'a> { // Don't report file sizes for directories. I've never looked // at one of those numbers and gained any information from it. if self.stat.kind == io::TypeDirectory { - Grey.paint("-") + GREY.paint("-") } else { let (size, suffix) = if use_iec_prefixes { format_IEC_bytes(self.stat.size) @@ -242,15 +242,15 @@ impl<'a> File<'a> { // The first three are bold because they're the ones used // most often. - File::permission_bit(bits, io::UserRead, "r", Yellow.bold()), - File::permission_bit(bits, io::UserWrite, "w", Red.bold()), - File::permission_bit(bits, io::UserExecute, "x", Green.bold().underline()), - File::permission_bit(bits, io::GroupRead, "r", Yellow.normal()), - File::permission_bit(bits, io::GroupWrite, "w", Red.normal()), - File::permission_bit(bits, io::GroupExecute, "x", Green.normal()), - File::permission_bit(bits, io::OtherRead, "r", Yellow.normal()), - File::permission_bit(bits, io::OtherWrite, "w", Red.normal()), - File::permission_bit(bits, io::OtherExecute, "x", Green.normal()), + File::permission_bit(bits, io::USER_READ, "r", Yellow.bold()), + File::permission_bit(bits, io::USER_WRITE, "w", Red.bold()), + File::permission_bit(bits, io::USER_EXECUTE, "x", Green.bold().underline()), + File::permission_bit(bits, io::GROUP_READ, "r", Yellow.normal()), + File::permission_bit(bits, io::GROUP_WRITE, "w", Red.normal()), + File::permission_bit(bits, io::GROUP_EXECUTE, "x", Green.normal()), + File::permission_bit(bits, io::OTHER_READ, "r", Yellow.normal()), + File::permission_bit(bits, io::OTHER_WRITE, "w", Red.normal()), + File::permission_bit(bits, io::OTHER_EXECUTE, "x", Green.normal()), ); } @@ -258,7 +258,7 @@ impl<'a> File<'a> { if bits.contains(bit) { style.paint(character.as_slice()) } else { - Grey.paint("-".as_slice()) + GREY.paint("-".as_slice()) } } } diff --git a/src/filetype.rs b/src/filetype.rs index 4bd3983..31b23ce 100644 --- a/src/filetype.rs +++ b/src/filetype.rs @@ -1,10 +1,10 @@ -use file::File; +use file::{File, GREY}; +use self::FileType::*; + use std::io; -use std::ascii::StrAsciiExt; +use std::ascii::AsciiExt; -use ansi_term::{Paint, Colour, Plain, Style, Red, Green, Yellow, Blue, Cyan, Fixed}; - -static Grey: Colour = Fixed(244); +use ansi_term::{Paint, Plain, Style, Red, Green, Yellow, Blue, Cyan, Fixed}; pub enum FileType { Normal, Directory, Executable, Immediate, Compiled, Symlink, Special, @@ -64,7 +64,7 @@ impl FileType { Crypto => Fixed(109).normal(), Document => Fixed(105).normal(), Compressed => Red.normal(), - Temp => Grey.normal(), + Temp => GREY.normal(), Immediate => Yellow.bold().underline(), Compiled => Fixed(137).normal(), } @@ -87,14 +87,14 @@ impl<'a> HasType for File<'a> { else if self.stat.kind == io::TypeBlockSpecial || self.stat.kind == io::TypeNamedPipe || self.stat.kind == io::TypeUnknown { return Special; } - else if self.stat.perm.contains(io::UserExecute) { + else if self.stat.perm.contains(io::USER_EXECUTE) { return Executable; } else if name.starts_with("README") || BUILD_TYPES.iter().any(|&s| s == name) { return Immediate; } else if self.ext.is_some() { - let e = self.ext.clone().unwrap().as_slice().to_ascii_lower(); + let e = self.ext.clone().unwrap().to_ascii_lower(); let ext = e.as_slice(); if IMAGE_TYPES.iter().any(|&s| s == ext) { return Image; diff --git a/src/options.rs b/src/options.rs index 2cd304b..824951c 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,9 +1,11 @@ extern crate getopts; use file::File; -use column::{Column, Permissions, FileName, FileSize, User, Group, HardLinks, Inode, Blocks}; -use std::ascii::StrAsciiExt; -use term; +use column::Column; +use column::Column::*; +use term::dimensions; + +use std::ascii::AsciiExt; pub enum SortField { Unsorted, Name, Extension, Size, FileInode @@ -12,12 +14,12 @@ pub enum SortField { impl SortField { fn from_word(word: String) -> SortField { match word.as_slice() { - "name" => Name, - "size" => Size, - "ext" => Extension, - "none" => Unsorted, - "inode" => FileInode, - _ => fail!("Invalid sorting order"), + "name" => SortField::Name, + "size" => SortField::Size, + "ext" => SortField::Extension, + "none" => SortField::Unsorted, + "inode" => SortField::FileInode, + _ => panic!("Invalid sorting order"), } } } @@ -40,7 +42,7 @@ pub struct Options { impl Options { pub fn getopts(args: Vec) -> Result { - let opts = [ + let opts = &[ getopts::optflag("1", "oneline", "display one entry per line"), getopts::optflag("a", "all", "show dot-files"), getopts::optflag("b", "binary", "use binary prefixes in file sizes"), @@ -61,7 +63,7 @@ impl Options { show_invisibles: matches.opt_present("all"), reverse: matches.opt_present("reverse"), header: matches.opt_present("header"), - sort_field: matches.opt_str("sort").map(|word| SortField::from_word(word)).unwrap_or(Name), + sort_field: matches.opt_str("sort").map(|word| SortField::from_word(word)).unwrap_or(SortField::Name), dirs: if matches.free.is_empty() { vec![ ".".to_string() ] } else { matches.free.clone() }, view: Options::view(matches), }) @@ -70,15 +72,15 @@ impl Options { fn view(matches: getopts::Matches) -> View { if matches.opt_present("long") { - Details(Options::columns(matches)) + View::Details(Options::columns(matches)) } else if matches.opt_present("oneline") { - Lines + View::Lines } else { - match term::dimensions() { - None => Lines, - Some((width, _)) => Grid(matches.opt_present("across"), width), + match dimensions() { + None => View::Lines, + Some((width, _)) => View::Grid(matches.opt_present("across"), width), } } } @@ -127,13 +129,13 @@ impl Options { .collect(); match self.sort_field { - Unsorted => {}, - Name => files.sort_by(|a, b| a.parts.cmp(&b.parts)), - Size => files.sort_by(|a, b| a.stat.size.cmp(&b.stat.size)), - FileInode => files.sort_by(|a, b| a.stat.unstable.inode.cmp(&b.stat.unstable.inode)), - Extension => files.sort_by(|a, b| { - let exts = a.ext.clone().map(|e| e.as_slice().to_ascii_lower()).cmp(&b.ext.clone().map(|e| e.as_slice().to_ascii_lower())); - let names = a.name.as_slice().to_ascii_lower().cmp(&b.name.as_slice().to_ascii_lower()); + SortField::Unsorted => {}, + SortField::Name => files.sort_by(|a, b| a.parts.cmp(&b.parts)), + SortField::Size => files.sort_by(|a, b| a.stat.size.cmp(&b.stat.size)), + SortField::FileInode => files.sort_by(|a, b| a.stat.unstable.inode.cmp(&b.stat.unstable.inode)), + SortField::Extension => files.sort_by(|a, b| { + let exts = a.ext.clone().map(|e| e.to_ascii_lower()).cmp(&b.ext.clone().map(|e| e.to_ascii_lower())); + let names = a.name.to_ascii_lower().cmp(&b.name.to_ascii_lower()); exts.cmp(&names) }), } diff --git a/src/sort.rs b/src/sort.rs index 453dd52..bd22f53 100644 --- a/src/sort.rs +++ b/src/sort.rs @@ -1,4 +1,5 @@ -use std::ascii::StrAsciiExt; +use self::SortPart::*; +use std::ascii::AsciiExt; // This is an implementation of "natural sort order". See // http://blog.codinghorror.com/sorting-for-humans-natural-sort-order/ @@ -20,11 +21,11 @@ impl SortPart { if is_digit { // numbers too big for a u64 fall back into strings. match from_str::(slice) { - Some(num) => Numeric(num), - None => Stringular(slice.to_string()), + Some(num) => SortPart::Numeric(num), + None => SortPart::Stringular(slice.to_string()), } } else { - Stringular(slice.to_ascii_lower()) + SortPart::Stringular(slice.to_ascii_lower()) } } @@ -38,11 +39,11 @@ impl SortPart { return parts } - let mut is_digit = input.as_slice().char_at(0).is_digit(); + let mut is_digit = input.as_slice().char_at(0).is_digit(10); let mut start = 0; for (i, c) in input.as_slice().char_indices() { - if is_digit != c.is_digit() { + if is_digit != c.is_digit(10) { parts.push(SortPart::from_string(is_digit, input.as_slice().slice(start, i))); is_digit = !is_digit; start = i; diff --git a/src/term.rs b/src/term.rs index 9e88adf..d0f52c6 100644 --- a/src/term.rs +++ b/src/term.rs @@ -21,12 +21,11 @@ mod c { // Unfortunately the actual command is not standardised... - #[cfg(target_os = "linux")] - #[cfg(target_os = "android")] + #[cfg(any(target_os = "linux", target_os = "android"))] + static TIOCGWINSZ: c_ulong = 0x5413; - #[cfg(target_os = "freebsd")] - #[cfg(target_os = "macos")] + #[cfg(any(target_os = "macos", target_os = "ios"))] static TIOCGWINSZ: c_ulong = 0x40087468; extern { diff --git a/src/unix.rs b/src/unix.rs index fac6a5f..1abf67f 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -1,6 +1,6 @@ use std::string::raw::from_buf; use std::ptr::read; -use std::collections::hashmap::HashMap; +use std::collections::HashMap; mod c { #![allow(non_camel_case_types)] @@ -127,13 +127,13 @@ impl Unix { pub fn load_group(&mut self, gid: u32) { match unsafe { c::getgrgid(gid).as_ref() } { None => { - self.group_names.find_or_insert(gid, None); - self.groups.find_or_insert(gid, false); + self.group_names.insert(gid, None); + self.groups.insert(gid, false); }, Some(r) => { let group_name = unsafe { Some(from_buf(r.gr_name as *const u8)) }; - self.groups.find_or_insert(gid, Unix::group_membership(r.gr_mem, &self.username)); - self.group_names.find_or_insert(gid, group_name); + self.groups.insert(gid, Unix::group_membership(r.gr_mem, &self.username)); + self.group_names.insert(gid, group_name); } }