options.rs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. extern crate getopts;
  2. use file::File;
  3. use std::cmp::lexical_ordering;
  4. pub enum SortField {
  5. Name, Extension, Size
  6. }
  7. pub struct Options {
  8. pub showInvisibles: bool,
  9. pub sortField: SortField,
  10. pub reverse: bool,
  11. pub dirs: Vec<StrBuf>,
  12. }
  13. impl SortField {
  14. pub fn from_word(word: StrBuf) -> SortField {
  15. match word.as_slice() {
  16. "name" => Name,
  17. "size" => Size,
  18. "ext" => Extension,
  19. _ => fail!("Invalid sorting order"),
  20. }
  21. }
  22. fn sort(&self, files: &mut Vec<File>) {
  23. match *self {
  24. Name => files.sort_by(|a, b| a.name.cmp(&b.name)),
  25. Size => files.sort_by(|a, b| a.stat.size.cmp(&b.stat.size)),
  26. Extension => files.sort_by(|a, b| {
  27. let exts = a.ext.cmp(&b.ext);
  28. let names = a.name.cmp(&b.name);
  29. lexical_ordering(exts, names)
  30. }),
  31. }
  32. }
  33. }
  34. impl Options {
  35. pub fn getopts(args: Vec<StrBuf>) -> Result<Options, getopts::Fail_> {
  36. let opts = ~[
  37. getopts::optflag("a", "all", "show dot-files"),
  38. getopts::optflag("r", "reverse", "reverse order of files"),
  39. getopts::optopt("s", "sort", "field to sort by", "WORD"),
  40. ];
  41. match getopts::getopts(args.tail(), opts) {
  42. Err(f) => Err(f),
  43. Ok(matches) => Ok(Options {
  44. showInvisibles: matches.opt_present("all"),
  45. reverse: matches.opt_present("reverse"),
  46. sortField: matches.opt_str("sort").map(|word| SortField::from_word(word)).unwrap_or(Name),
  47. dirs: matches.free,
  48. })
  49. }
  50. }
  51. pub fn sort(&self, files: &mut Vec<File>) {
  52. self.sortField.sort(files);
  53. }
  54. pub fn show(&self, f: &File) -> bool {
  55. if self.showInvisibles {
  56. true
  57. } else {
  58. !f.name.starts_with(".")
  59. }
  60. }
  61. }