Format file size in bytes with the user's locale

Use the `locale` crate as a dependency to read in the set
thousands-separator character, and pass this to the file size column,
which uses it to add the separators in.

en_GB uses ","
fr_FR uses "" and just displays the numbers in one go.
This commit is contained in:
Ben S 2015-02-10 16:08:10 +00:00
parent f3c3a02e98
commit 21ac16f808
6 changed files with 24 additions and 9 deletions

6
Cargo.lock generated
View File

@ -7,6 +7,7 @@ dependencies = [
"datetime_macros 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "datetime_macros 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"git2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"locale 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"natord 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "natord 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"number_prefix 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pad 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "pad 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -121,6 +122,11 @@ dependencies = [
"pkg-config 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "locale"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "log" name = "log"
version = "0.2.3" version = "0.2.3"

View File

@ -10,6 +10,7 @@ name = "exa"
ansi_term = "0.4.5" ansi_term = "0.4.5"
datetime_macros = "0.1.2" datetime_macros = "0.1.2"
getopts = "0.2.1" getopts = "0.2.1"
locale = "0.1.1"
natord = "1.0.7" natord = "1.0.7"
number_prefix = "0.2.3" number_prefix = "0.2.3"
pad = "0.1.1" pad = "0.1.1"

View File

@ -10,6 +10,8 @@ use users::Users;
use pad::Alignment; use pad::Alignment;
use locale;
use number_prefix::{binary_prefix, decimal_prefix, Prefixed, Standalone, PrefixNames}; use number_prefix::{binary_prefix, decimal_prefix, Prefixed, Standalone, PrefixNames};
use datetime; use datetime;
@ -97,10 +99,10 @@ impl<'a> File<'a> {
} }
/// Get the data for a column, formatted as a coloured string. /// Get the data for a column, formatted as a coloured string.
pub fn display<U: Users>(&self, column: &Column, users_cache: &mut U) -> Cell { pub fn display<U: Users>(&self, column: &Column, users_cache: &mut U, locale: &locale::Numeric) -> Cell {
match *column { match *column {
Permissions => self.permissions_string(), Permissions => self.permissions_string(),
FileSize(f) => self.file_size(f), FileSize(f) => self.file_size(f, locale),
Timestamp(t, y) => self.timestamp(t, y), Timestamp(t, y) => self.timestamp(t, y),
HardLinks => self.hard_links(), HardLinks => self.hard_links(),
Inode => self.inode(), Inode => self.inode(),
@ -277,7 +279,7 @@ impl<'a> File<'a> {
/// some filesystems, I've never looked at one of those numbers and gained /// some filesystems, I've never looked at one of those numbers and gained
/// any information from it, so by emitting "-" instead, the table is less /// any information from it, so by emitting "-" instead, the table is less
/// cluttered with numbers. /// cluttered with numbers.
fn file_size(&self, size_format: SizeFormat) -> Cell { fn file_size(&self, size_format: SizeFormat, locale: &locale::Numeric) -> Cell {
if self.stat.kind == io::FileType::Directory { if self.stat.kind == io::FileType::Directory {
Cell { text: GREY.paint("-").to_string(), length: 1 } Cell { text: GREY.paint("-").to_string(), length: 1 }
} }
@ -285,9 +287,12 @@ impl<'a> File<'a> {
let result = match size_format { let result = match size_format {
SizeFormat::DecimalBytes => decimal_prefix(self.stat.size as f64), SizeFormat::DecimalBytes => decimal_prefix(self.stat.size as f64),
SizeFormat::BinaryBytes => binary_prefix(self.stat.size as f64), SizeFormat::BinaryBytes => binary_prefix(self.stat.size as f64),
SizeFormat::JustBytes => return Cell::paint(Green.bold(), &*self.stat.size.to_string()) SizeFormat::JustBytes => {
return Cell::paint(Green.bold(), &locale.format_int(self.stat.size as isize)[])
},
}; };
match result { match result {
Standalone(bytes) => Cell::paint(Green.bold(), &*bytes.to_string()), Standalone(bytes) => Cell::paint(Green.bold(), &*bytes.to_string()),
Prefixed(prefix, n) => { Prefixed(prefix, n) => {

View File

@ -6,6 +6,7 @@ extern crate datetime_macros;
extern crate ansi_term; extern crate ansi_term;
extern crate datetime; extern crate datetime;
extern crate getopts; extern crate getopts;
extern crate locale;
extern crate natord; extern crate natord;
extern crate number_prefix; extern crate number_prefix;
extern crate pad; extern crate pad;

View File

@ -32,7 +32,7 @@ pub struct FileFilter {
sort_field: SortField, sort_field: SortField,
} }
#[derive(PartialEq, Copy, Debug)] #[derive(PartialEq, Debug, Copy)]
pub enum View { pub enum View {
Details(Details), Details(Details),
Lines, Lines,

View File

@ -4,6 +4,7 @@ use file::{File, GREY};
use options::{Columns, FileFilter}; use options::{Columns, FileFilter};
use users::OSUsers; use users::OSUsers;
use locale;
use ansi_term::Style::Plain; use ansi_term::Style::Plain;
#[derive(PartialEq, Debug, Copy)] #[derive(PartialEq, Debug, Copy)]
@ -24,9 +25,10 @@ impl Details {
// padding the fields during output. // padding the fields during output.
let columns = self.columns.for_dir(dir); let columns = self.columns.for_dir(dir);
let locale = locale::Numeric::load_user_locale().unwrap_or_else(|_| locale::Numeric::default());
let mut cache = OSUsers::empty_cache(); let mut cache = OSUsers::empty_cache();
let mut table = Vec::new(); let mut table = Vec::new();
self.get_files(&columns[], &mut cache, &mut table, files, 0); self.get_files(&columns[], &mut cache, &locale, &mut table, files, 0);
if self.header { if self.header {
let row = Row { let row = Row {
@ -73,12 +75,12 @@ impl Details {
} }
} }
fn get_files(&self, columns: &[Column], cache: &mut OSUsers, dest: &mut Vec<Row>, src: &[File], depth: usize) { fn get_files(&self, columns: &[Column], cache: &mut OSUsers, locale: &locale::Numeric, dest: &mut Vec<Row>, src: &[File], depth: usize) {
for (index, file) in src.iter().enumerate() { for (index, file) in src.iter().enumerate() {
let row = Row { let row = Row {
depth: depth, depth: depth,
cells: columns.iter().map(|c| file.display(c, cache)).collect(), cells: columns.iter().map(|c| file.display(c, cache, locale)).collect(),
name: file.file_name_view(), name: file.file_name_view(),
last: index == src.len() - 1, last: index == src.len() - 1,
children: file.this.is_some(), children: file.this.is_some(),
@ -90,7 +92,7 @@ impl Details {
if let Some(ref dir) = file.this { if let Some(ref dir) = file.this {
let mut files = dir.files(true); let mut files = dir.files(true);
self.filter.transform_files(&mut files); self.filter.transform_files(&mut files);
self.get_files(columns, cache, dest, files.as_slice(), depth + 1); self.get_files(columns, cache, locale, dest, files.as_slice(), depth + 1);
} }
} }
} }