diff --git a/src/batch.rs b/src/batch.rs index 1112ead..498b450 100644 --- a/src/batch.rs +++ b/src/batch.rs @@ -1,3 +1,4 @@ +use ansi_term::{ANSIString, ANSIStrings}; use meta::FileType; use meta::Meta; use std::cmp::Ordering; @@ -19,7 +20,7 @@ impl Batch { let mut res = Vec::with_capacity(self.0.len()); for meta in &self.0 { - res.push(meta.name.render()); + res.push(meta.name.render().to_string()); } res @@ -33,22 +34,29 @@ impl Batch { let (max_size_value_length, max_size_unit_length) = self.detect_size_lenghts(); for meta in &self.0 { - let mut link_str = String::new(); + let mut link_str = ANSIString::from(""); if let Some(ref symlink) = meta.symlink { link_str = symlink.render(); } - res.push(format!( - "{}{} {} {} {} {}{}", + let strings: &[ANSIString] = &[ meta.file_type.render(), meta.permissions.render(), - meta.owner.render(max_user_length, max_group_length), + ANSIString::from(" "), + meta.owner.render_user(max_user_length), + ANSIString::from(" "), + meta.owner.render_group(max_group_length), + ANSIString::from(" "), meta.size .render(max_size_value_length, max_size_unit_length), + ANSIString::from(" "), meta.date.render(), + ANSIString::from(" "), meta.name.render(), link_str, - )); + ]; + + res.push(ANSIStrings(strings).to_string()); } res @@ -58,7 +66,7 @@ impl Batch { let mut max: usize = 0; for meta in &self.0 { - let user = meta.owner.render_user(); + let user = meta.owner.user(); if user.len() > max { max = user.len(); } @@ -71,7 +79,7 @@ impl Batch { let mut max: usize = 0; for meta in &self.0 { - let group = meta.owner.render_group(); + let group = meta.owner.group(); if group.len() > max { max = group.len(); } diff --git a/src/display.rs b/src/display.rs index b6b829f..07341b0 100644 --- a/src/display.rs +++ b/src/display.rs @@ -44,13 +44,13 @@ impl<'a> Display<'a> { ); } - fn print_one_per_line(&self, outputs: &Vec) { + fn print_one_per_line(&self, outputs: &[String]) { for output in outputs { println!("{}", output); } } - fn get_visible_width(&self, input: &String) -> usize { + fn get_visible_width(&self, input: &str) -> usize { let mut nb_invisible_char = 0; for (idx, _) in input.match_indices("[38;5;") { diff --git a/src/meta/date.rs b/src/meta/date.rs index 3af6320..31c6c1d 100644 --- a/src/meta/date.rs +++ b/src/meta/date.rs @@ -1,3 +1,4 @@ +use ansi_term::ANSIString; use color::{Colors, Elem}; use std::fs::Metadata; use std::time::UNIX_EPOCH; @@ -24,7 +25,7 @@ impl<'a> From<&'a Metadata> for Date { } impl Date { - pub fn render(&self) -> String { + pub fn render(&self) -> ANSIString { let now = time::now(); let color; @@ -36,6 +37,6 @@ impl Date { color = Colors[&Elem::Older]; } - color.paint(self.0.ctime().to_string()).to_string() + color.paint(self.0.ctime().to_string()) } } diff --git a/src/meta/filetype.rs b/src/meta/filetype.rs index 7d22a3b..2ec3bcf 100644 --- a/src/meta/filetype.rs +++ b/src/meta/filetype.rs @@ -1,3 +1,4 @@ +use ansi_term::ANSIString; use color::{Colors, Elem}; use std::fs::Metadata; use std::os::unix::fs::FileTypeExt; @@ -39,16 +40,16 @@ impl<'a> From<&'a Metadata> for FileType { } impl FileType { - pub fn render(self) -> String { + pub fn render(self) -> ANSIString<'static> { match self { - FileType::File => Colors[&Elem::File].paint(".").to_string(), - FileType::Directory => Colors[&Elem::Dir].paint("d").to_string(), - FileType::Pipe => Colors[&Elem::Pipe].paint("|").to_string(), - FileType::SymLink => Colors[&Elem::SymLink].paint("l").to_string(), - FileType::BlockDevice => Colors[&Elem::BlockDevice].paint("b").to_string(), - FileType::CharDevice => Colors[&Elem::CharDevice].paint("c").to_string(), - FileType::Socket => Colors[&Elem::Socket].paint("s").to_string(), - FileType::Special => Colors[&Elem::Special].paint("?").to_string(), + FileType::File => Colors[&Elem::File].paint("."), + FileType::Directory => Colors[&Elem::Dir].paint("d"), + FileType::Pipe => Colors[&Elem::Pipe].paint("|"), + FileType::SymLink => Colors[&Elem::SymLink].paint("l"), + FileType::BlockDevice => Colors[&Elem::BlockDevice].paint("b"), + FileType::CharDevice => Colors[&Elem::CharDevice].paint("c"), + FileType::Socket => Colors[&Elem::Socket].paint("s"), + FileType::Special => Colors[&Elem::Special].paint("?"), } } } diff --git a/src/meta/name.rs b/src/meta/name.rs index 83f048a..5914e9b 100644 --- a/src/meta/name.rs +++ b/src/meta/name.rs @@ -1,3 +1,4 @@ +use ansi_term::ANSIString; use color::{Colors, Elem}; use icon; use meta::filetype::FileType; @@ -40,7 +41,7 @@ impl Name { } } - pub fn render(&self) -> String { + pub fn render(&self) -> ANSIString { let mut content = String::with_capacity(self.name.len() + 3 /* spaces */); let color = if self.file_type == FileType::Directory { @@ -53,7 +54,7 @@ impl Name { content += " "; content += &self.name; - color.paint(content).to_string() + color.paint(content) } pub fn name(&self) -> String { diff --git a/src/meta/owner.rs b/src/meta/owner.rs index 8108d4f..9a5bc5c 100644 --- a/src/meta/owner.rs +++ b/src/meta/owner.rs @@ -1,3 +1,4 @@ +use ansi_term::ANSIString; use color::{Colors, Elem}; use std::fs::Metadata; use std::os::unix::fs::MetadataExt; @@ -30,31 +31,31 @@ impl<'a> From<&'a Metadata> for Owner { } impl Owner { - pub fn render(&self, user_alignment: usize, group_alignment: usize) -> String { - let mut content = - String::with_capacity(user_alignment + group_alignment + 2 /* spaces */); - - content += &Colors[&Elem::User].paint(&self.user).to_string(); - for _ in 0..(user_alignment - self.user.len()) { - content.push(' '); - } - - // the space between the name and the group. - content.push(' '); - - content += &Colors[&Elem::Group].paint(&self.group).to_string(); - for _ in 0..(group_alignment - self.group.len()) { - content.push(' '); - } - - content - } - - pub fn render_user(&self) -> String { + pub fn user(&self) -> String { self.user.clone() } - pub fn render_group(&self) -> String { + pub fn group(&self) -> String { self.group.clone() } + + pub fn render_user(&self, user_alignment: usize) -> ANSIString { + let mut alignment = String::with_capacity(user_alignment - self.user.len()); + + for _ in 0..(user_alignment - self.user.len()) { + alignment.push(' '); + } + + Colors[&Elem::User].paint(alignment + &self.user) + } + + pub fn render_group(&self, group_alignment: usize) -> ANSIString { + let mut alignment = String::with_capacity(group_alignment - self.group.len()); + + for _ in 0..(group_alignment - self.group.len()) { + alignment.push(' '); + } + + Colors[&Elem::Group].paint(alignment + &self.group) + } } diff --git a/src/meta/permissions.rs b/src/meta/permissions.rs index 6682faa..d698476 100644 --- a/src/meta/permissions.rs +++ b/src/meta/permissions.rs @@ -1,4 +1,4 @@ -use ansi_term::{ANSIString, Colour}; +use ansi_term::{ANSIString, ANSIStrings, Colour}; use color::{Colors, Elem}; use std::fs::Metadata; use std::os::unix::fs::PermissionsExt; @@ -48,28 +48,29 @@ impl<'a> From<&'a Metadata> for Permissions { } impl Permissions { - pub fn render(&self) -> String { - let mut res = String::with_capacity(11); - + pub fn render(&self) -> ANSIString { let bit = |bit, chr: &'static str, color: Colour| { if bit { - color.paint(chr).to_string() + color.paint(chr) } else { - Colors[&Elem::NoAccess].paint("-").to_string() + Colors[&Elem::NoAccess].paint("-") } }; - res += &bit(self.user_read, "r", Colors[&Elem::Read]); - res += &bit(self.user_write, "w", Colors[&Elem::Write]); - res += &self.execute_bit(self.setuid).to_string(); - res += &bit(self.group_read, "r", Colors[&Elem::Read]); - res += &bit(self.group_write, "w", Colors[&Elem::Write]); - res += &self.execute_bit(self.setgid).to_string(); - res += &bit(self.other_read, "r", Colors[&Elem::Read]); - res += &bit(self.other_write, "w", Colors[&Elem::Write]); - res += &self.other_execute_bit().to_string(); + let strings: &[ANSIString<'static>] = &[ + bit(self.user_read, "r", Colors[&Elem::Read]), + bit(self.user_write, "w", Colors[&Elem::Write]), + self.execute_bit(self.setuid), + bit(self.group_read, "r", Colors[&Elem::Read]), + bit(self.group_write, "w", Colors[&Elem::Write]), + self.execute_bit(self.setgid), + bit(self.other_read, "r", Colors[&Elem::Read]), + bit(self.other_write, "w", Colors[&Elem::Write]), + self.other_execute_bit(), + ]; - res + let res = ANSIStrings(strings).to_string(); + ANSIString::from(res) } fn execute_bit(&self, special: bool) -> ANSIString<'static> { diff --git a/src/meta/size.rs b/src/meta/size.rs index 423cae4..1d2bc9e 100644 --- a/src/meta/size.rs +++ b/src/meta/size.rs @@ -1,3 +1,4 @@ +use ansi_term::ANSIString; use color::{Colors, Elem}; use std::fs::Metadata; @@ -50,7 +51,7 @@ impl<'a> From<&'a Metadata> for Size { } impl Size { - pub fn render(&self, value_alignment: usize, unit_alignment: usize) -> String { + pub fn render(&self, value_alignment: usize, unit_alignment: usize) -> ANSIString { let mut content = String::with_capacity(value_alignment + unit_alignment + 1); let value = self.render_value(); @@ -71,13 +72,13 @@ impl Size { self.paint(content) } - fn paint(&self, content: String) -> String { + fn paint(&self, content: String) -> ANSIString { if self.unit == Unit::Byte || self.unit == Unit::Kilo { - Colors[&Elem::FileSmall].paint(content).to_string() + Colors[&Elem::FileSmall].paint(content) } else if self.unit == Unit::Mega { - Colors[&Elem::FileMedium].paint(content).to_string() + Colors[&Elem::FileMedium].paint(content) } else { - Colors[&Elem::FileLarge].paint(content).to_string() + Colors[&Elem::FileLarge].paint(content) } } diff --git a/src/meta/symlink.rs b/src/meta/symlink.rs index de91d0e..0f4b5b7 100644 --- a/src/meta/symlink.rs +++ b/src/meta/symlink.rs @@ -1,3 +1,4 @@ +use ansi_term::ANSIString; use color::{Colors, Elem}; use std::path::PathBuf; @@ -15,9 +16,7 @@ impl<'a> From<&'a PathBuf> for SymLink { } impl SymLink { - pub fn render(&self) -> String { - Colors[&Elem::SymLink] - .paint(String::from(" ⇒ ") + &self.0) - .to_string() + pub fn render(&self) -> ANSIString { + Colors[&Elem::SymLink].paint(String::from(" ⇒ ") + &self.0) } }