options.rs 2.3 KB

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