fields.rs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. //! Wrapper types for the values returned from `File`s.
  2. //!
  3. //! The methods of `File` that return information about the entry on the
  4. //! filesystem -- size, modification date, block count, or Git status -- used
  5. //! to just return these as formatted strings, but this became inflexible once
  6. //! customisable output styles landed.
  7. //!
  8. //! Instead, they will return a wrapper type from this module, which tags the
  9. //! type with what field it is while containing the actual raw value.
  10. //!
  11. //! The `output::details` module, among others, uses these types to render and
  12. //! display the information as formatted strings.
  13. // C-style `blkcnt_t` types don’t follow Rust’s rules!
  14. #![allow(non_camel_case_types)]
  15. /// The type of a file’s block count.
  16. pub type blkcnt_t = u64;
  17. /// The type of a file’s group ID.
  18. pub type gid_t = u32;
  19. /// The type of a file’s inode.
  20. pub type ino_t = u64;
  21. /// The type of a file’s number of links.
  22. pub type nlink_t = u64;
  23. /// The type of a file’s timestamp (creation, modification, access, etc).
  24. pub type time_t = i64;
  25. /// The type of a file’s user ID.
  26. pub type uid_t = u32;
  27. /// The file’s base type, which gets displayed in the very first column of the
  28. /// details output.
  29. ///
  30. /// This type is set entirely by the filesystem, rather than relying on a
  31. /// file’s contents. So “link” is a type, but “image” is just a type of
  32. /// regular file. (See the `filetype` module for those checks.)
  33. ///
  34. /// Its ordering is used when sorting by type.
  35. #[derive(PartialEq, Eq, PartialOrd, Ord)]
  36. pub enum Type {
  37. Directory, File, Link, Pipe, Socket, CharDevice, BlockDevice, Special,
  38. }
  39. impl Type {
  40. pub fn is_regular_file(&self) -> bool {
  41. match *self {
  42. Type::File => true,
  43. _ => false,
  44. }
  45. }
  46. }
  47. /// The file’s Unix permission bitfield, with one entry per bit.
  48. pub struct Permissions {
  49. pub user_read: bool,
  50. pub user_write: bool,
  51. pub user_execute: bool,
  52. pub group_read: bool,
  53. pub group_write: bool,
  54. pub group_execute: bool,
  55. pub other_read: bool,
  56. pub other_write: bool,
  57. pub other_execute: bool,
  58. pub sticky: bool,
  59. pub setgid: bool,
  60. pub setuid: bool,
  61. }
  62. /// The three pieces of information that are displayed as a single column in
  63. /// the details view. These values are fused together to make the output a
  64. /// little more compressed.
  65. pub struct PermissionsPlus {
  66. pub file_type: Type,
  67. pub permissions: Permissions,
  68. pub xattrs: bool,
  69. }
  70. /// A file’s number of hard links on the filesystem.
  71. ///
  72. /// Under Unix, a file can exist on the filesystem only once but appear in
  73. /// multiple directories. However, it’s rare (but occasionally useful!) for a
  74. /// regular file to have a link count greater than 1, so we highlight the
  75. /// block count specifically for this case.
  76. pub struct Links {
  77. /// The actual link count.
  78. pub count: nlink_t,
  79. /// Whether this file is a regular file with more than one hard link.
  80. pub multiple: bool,
  81. }
  82. /// A file’s inode. Every directory entry on a Unix filesystem has an inode,
  83. /// including directories and links, so this is applicable to everything exa
  84. /// can deal with.
  85. pub struct Inode(pub ino_t);
  86. /// The number of blocks that a file takes up on the filesystem, if any.
  87. pub enum Blocks {
  88. /// This file has the given number of blocks.
  89. Some(blkcnt_t),
  90. /// This file isn’t of a type that can take up blocks.
  91. None,
  92. }
  93. /// The ID of the user that owns a file. This will only ever be a number;
  94. /// looking up the username is done in the `display` module.
  95. pub struct User(pub uid_t);
  96. /// The ID of the group that a file belongs to.
  97. pub struct Group(pub gid_t);
  98. /// A file’s size, in bytes. This is usually formatted by the `number_prefix`
  99. /// crate into something human-readable.
  100. pub enum Size {
  101. /// This file has a defined size.
  102. Some(u64),
  103. /// This file has no size, or has a size but we aren’t interested in it.
  104. ///
  105. /// Under Unix, directory entries that aren’t regular files will still
  106. /// have a file size. For example, a directory will just contain a list of
  107. /// its files as its “contents” and will be specially flagged as being a
  108. /// directory, rather than a file. However, seeing the “file size” of this
  109. /// data is rarely useful -- I can’t think of a time when I’ve seen it and
  110. /// learnt something. So we discard it and just output “-” instead.
  111. ///
  112. /// See this answer for more: http://unix.stackexchange.com/a/68266
  113. None,
  114. /// This file is a block or character device, so instead of a size, print
  115. /// out the file’s major and minor device IDs.
  116. ///
  117. /// This is what ls does as well. Without it, the devices will just have
  118. /// file sizes of zero.
  119. DeviceIDs(DeviceIDs),
  120. }
  121. /// The major and minor device IDs that gets displayed for device files.
  122. ///
  123. /// You can see what these device numbers mean:
  124. /// - http://www.lanana.org/docs/device-list/
  125. /// - http://www.lanana.org/docs/device-list/devices-2.6+.txt
  126. pub struct DeviceIDs {
  127. pub major: u8,
  128. pub minor: u8,
  129. }
  130. /// One of a file’s timestamps (created, accessed, or modified).
  131. #[derive(Copy, Clone)]
  132. pub struct Time {
  133. pub seconds: time_t,
  134. pub nanoseconds: time_t,
  135. }
  136. /// A file’s status in a Git repository. Whether a file is in a repository or
  137. /// not is handled by the Git module, rather than having a “null” variant in
  138. /// this enum.
  139. pub enum GitStatus {
  140. /// This file hasn’t changed since the last commit.
  141. NotModified,
  142. /// This file didn’t exist for the last commit, and is not specified in
  143. /// the ignored files list.
  144. New,
  145. /// A file that’s been modified since the last commit.
  146. Modified,
  147. /// A deleted file. This can’t ever be shown, but it’s here anyway!
  148. Deleted,
  149. /// A file that Git has tracked a rename for.
  150. Renamed,
  151. /// A file that’s had its type (such as the file permissions) changed.
  152. TypeChange,
  153. }
  154. /// A file’s complete Git status. It’s possible to make changes to a file, add
  155. /// it to the staging area, then make *more* changes, so we need to list each
  156. /// file’s status for both of these.
  157. pub struct Git {
  158. pub staged: GitStatus,
  159. pub unstaged: GitStatus,
  160. }
  161. impl Git {
  162. /// Create a Git status for a file with nothing done to it.
  163. pub fn empty() -> Git {
  164. Git { staged: GitStatus::NotModified, unstaged: GitStatus::NotModified }
  165. }
  166. }