options.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. extern crate getopts;
  2. use file::File;
  3. use std::cmp::lexical_ordering;
  4. use column::{Column, Permissions, FileName, FileSize, User, Group};
  5. pub enum SortField {
  6. Name, Extension, Size
  7. }
  8. pub struct Options {
  9. pub showInvisibles: bool,
  10. pub sortField: SortField,
  11. pub reverse: bool,
  12. pub dirs: Vec<String>,
  13. pub columns: ~[Column],
  14. }
  15. impl SortField {
  16. fn from_word(word: String) -> SortField {
  17. match word.as_slice() {
  18. "name" => Name,
  19. "size" => Size,
  20. "ext" => Extension,
  21. _ => fail!("Invalid sorting order"),
  22. }
  23. }
  24. }
  25. impl Options {
  26. pub fn getopts(args: Vec<String>) -> Result<Options, getopts::Fail_> {
  27. let opts = ~[
  28. getopts::optflag("a", "all", "show dot-files"),
  29. getopts::optflag("b", "binary", "use binary prefixes in file sizes"),
  30. getopts::optflag("r", "reverse", "reverse order of files"),
  31. getopts::optopt("s", "sort", "field to sort by", "WORD"),
  32. ];
  33. match getopts::getopts(args.tail(), opts) {
  34. Err(f) => Err(f),
  35. Ok(matches) => Ok(Options {
  36. showInvisibles: matches.opt_present("all"),
  37. reverse: matches.opt_present("reverse"),
  38. sortField: matches.opt_str("sort").map(|word| SortField::from_word(word)).unwrap_or(Name),
  39. dirs: matches.free.clone(),
  40. columns: Options::columns(matches),
  41. })
  42. }
  43. }
  44. fn columns(matches: getopts::Matches) -> ~[Column] {
  45. return ~[
  46. Permissions,
  47. FileSize(matches.opt_present("binary")),
  48. User,
  49. Group,
  50. FileName,
  51. ];
  52. }
  53. fn show(&self, f: &File) -> bool {
  54. if self.showInvisibles {
  55. true
  56. } else {
  57. !f.name.starts_with(".")
  58. }
  59. }
  60. pub fn transform_files<'a>(&self, unordered_files: &'a Vec<File<'a>>) -> Vec<&'a File<'a>> {
  61. let mut files: Vec<&'a File<'a>> = unordered_files.iter()
  62. .filter(|&f| self.show(f))
  63. .collect();
  64. match self.sortField {
  65. Name => files.sort_by(|a, b| a.name.cmp(&b.name)),
  66. Size => files.sort_by(|a, b| a.stat.size.cmp(&b.stat.size)),
  67. Extension => files.sort_by(|a, b| {
  68. let exts = a.ext.cmp(&b.ext);
  69. let names = a.name.cmp(&b.name);
  70. lexical_ordering(exts, names)
  71. }),
  72. }
  73. if self.reverse {
  74. files.reverse();
  75. }
  76. return files;
  77. }
  78. }