column.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. use fs::Dir;
  2. #[derive(PartialEq, Debug, Copy, Clone)]
  3. pub enum Column {
  4. Permissions,
  5. FileSize(SizeFormat),
  6. Timestamp(TimeType),
  7. Blocks,
  8. User,
  9. Group,
  10. HardLinks,
  11. Inode,
  12. GitStatus,
  13. }
  14. /// Each column can pick its own **Alignment**. Usually, numbers are
  15. /// right-aligned, and text is left-aligned.
  16. #[derive(Copy, Clone)]
  17. pub enum Alignment {
  18. Left, Right,
  19. }
  20. impl Column {
  21. /// Get the alignment this column should use.
  22. pub fn alignment(&self) -> Alignment {
  23. match *self {
  24. Column::FileSize(_) => Alignment::Right,
  25. Column::HardLinks => Alignment::Right,
  26. Column::Inode => Alignment::Right,
  27. Column::Blocks => Alignment::Right,
  28. Column::GitStatus => Alignment::Right,
  29. _ => Alignment::Left,
  30. }
  31. }
  32. /// Get the text that should be printed at the top, when the user elects
  33. /// to have a header row printed.
  34. pub fn header(&self) -> &'static str {
  35. match *self {
  36. Column::Permissions => "Permissions",
  37. Column::FileSize(_) => "Size",
  38. Column::Timestamp(t) => t.header(),
  39. Column::Blocks => "Blocks",
  40. Column::User => "User",
  41. Column::Group => "Group",
  42. Column::HardLinks => "Links",
  43. Column::Inode => "inode",
  44. Column::GitStatus => "Git",
  45. }
  46. }
  47. }
  48. #[derive(PartialEq, Copy, Clone, Debug, Default)]
  49. pub struct Columns {
  50. pub size_format: SizeFormat,
  51. pub time_types: TimeTypes,
  52. pub inode: bool,
  53. pub links: bool,
  54. pub blocks: bool,
  55. pub group: bool,
  56. pub git: bool
  57. }
  58. impl Columns {
  59. pub fn should_scan_for_git(&self) -> bool {
  60. self.git
  61. }
  62. pub fn for_dir(&self, dir: Option<&Dir>) -> Vec<Column> {
  63. let mut columns = vec![];
  64. if self.inode {
  65. columns.push(Column::Inode);
  66. }
  67. columns.push(Column::Permissions);
  68. if self.links {
  69. columns.push(Column::HardLinks);
  70. }
  71. columns.push(Column::FileSize(self.size_format));
  72. if self.blocks {
  73. columns.push(Column::Blocks);
  74. }
  75. columns.push(Column::User);
  76. if self.group {
  77. columns.push(Column::Group);
  78. }
  79. if self.time_types.modified {
  80. columns.push(Column::Timestamp(TimeType::Modified));
  81. }
  82. if self.time_types.created {
  83. columns.push(Column::Timestamp(TimeType::Created));
  84. }
  85. if self.time_types.accessed {
  86. columns.push(Column::Timestamp(TimeType::Accessed));
  87. }
  88. if cfg!(feature="git") {
  89. if let Some(d) = dir {
  90. if self.should_scan_for_git() && d.has_git_repo() {
  91. columns.push(Column::GitStatus);
  92. }
  93. }
  94. }
  95. columns
  96. }
  97. }
  98. /// Formatting options for file sizes.
  99. #[derive(PartialEq, Debug, Copy, Clone)]
  100. pub enum SizeFormat {
  101. /// Format the file size using **decimal** prefixes, such as “kilo”,
  102. /// “mega”, or “giga”.
  103. DecimalBytes,
  104. /// Format the file size using **binary** prefixes, such as “kibi”,
  105. /// “mebi”, or “gibi”.
  106. BinaryBytes,
  107. /// Do no formatting and just display the size as a number of bytes.
  108. JustBytes,
  109. }
  110. impl Default for SizeFormat {
  111. fn default() -> SizeFormat {
  112. SizeFormat::DecimalBytes
  113. }
  114. }
  115. /// The types of a file’s time fields. These three fields are standard
  116. /// across most (all?) operating systems.
  117. #[derive(PartialEq, Debug, Copy, Clone)]
  118. pub enum TimeType {
  119. /// The file’s accessed time (`st_atime`).
  120. Accessed,
  121. /// The file’s modified time (`st_mtime`).
  122. Modified,
  123. /// The file’s creation time (`st_ctime`).
  124. Created,
  125. }
  126. impl TimeType {
  127. /// Returns the text to use for a column’s heading in the columns output.
  128. pub fn header(&self) -> &'static str {
  129. match *self {
  130. TimeType::Accessed => "Date Accessed",
  131. TimeType::Modified => "Date Modified",
  132. TimeType::Created => "Date Created",
  133. }
  134. }
  135. }
  136. /// Fields for which of a file’s time fields should be displayed in the
  137. /// columns output.
  138. ///
  139. /// There should always be at least one of these--there's no way to disable
  140. /// the time columns entirely (yet).
  141. #[derive(PartialEq, Debug, Copy, Clone)]
  142. pub struct TimeTypes {
  143. pub accessed: bool,
  144. pub modified: bool,
  145. pub created: bool,
  146. }
  147. impl Default for TimeTypes {
  148. /// By default, display just the ‘modified’ time. This is the most
  149. /// common option, which is why it has this shorthand.
  150. fn default() -> TimeTypes {
  151. TimeTypes { accessed: false, modified: true, created: false }
  152. }
  153. }