fields.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. #![allow(clippy::struct_excessive_bools)]
  16. /// The type of a file’s block count.
  17. pub type blkcnt_t = u64;
  18. /// The type of a file’s group ID.
  19. pub type gid_t = u32;
  20. /// The type of a file’s inode.
  21. pub type ino_t = u64;
  22. /// The type of a file’s number of links.
  23. pub type nlink_t = u64;
  24. /// The type of a file’s timestamp (creation, modification, access, etc).
  25. pub type time_t = i64;
  26. /// The type of a file’s user ID.
  27. pub type uid_t = u32;
  28. /// The file’s base type, which gets displayed in the very first column of the
  29. /// details output.
  30. ///
  31. /// This type is set entirely by the filesystem, rather than relying on a
  32. /// file’s contents. So “link” is a type, but “image” is just a type of
  33. /// regular file. (See the `filetype` module for those checks.)
  34. ///
  35. /// Its ordering is used when sorting by type.
  36. #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
  37. pub enum Type {
  38. Directory,
  39. File,
  40. Link,
  41. Pipe,
  42. Socket,
  43. CharDevice,
  44. BlockDevice,
  45. Special,
  46. }
  47. impl Type {
  48. pub fn is_regular_file(self) -> bool {
  49. matches!(self, Self::File)
  50. }
  51. }
  52. /// The file’s Unix permission bitfield, with one entry per bit.
  53. #[derive(Copy, Clone)]
  54. pub struct Permissions {
  55. pub user_read: bool,
  56. pub user_write: bool,
  57. pub user_execute: bool,
  58. pub group_read: bool,
  59. pub group_write: bool,
  60. pub group_execute: bool,
  61. pub other_read: bool,
  62. pub other_write: bool,
  63. pub other_execute: bool,
  64. pub sticky: bool,
  65. pub setgid: bool,
  66. pub setuid: bool,
  67. }
  68. /// The file's `FileAttributes` field, available only on Windows.
  69. #[derive(Copy, Clone)]
  70. pub struct Attributes {
  71. pub archive: bool,
  72. pub directory: bool,
  73. pub readonly: bool,
  74. pub hidden: bool,
  75. pub system: bool,
  76. pub reparse_point: bool,
  77. }
  78. /// The three pieces of information that are displayed as a single column in
  79. /// the details view. These values are fused together to make the output a
  80. /// little more compressed.
  81. #[derive(Copy, Clone)]
  82. pub struct PermissionsPlus {
  83. pub file_type: Type,
  84. #[cfg(unix)]
  85. pub permissions: Permissions,
  86. #[cfg(windows)]
  87. pub attributes: Attributes,
  88. pub xattrs: bool,
  89. }
  90. /// The permissions encoded as octal values
  91. #[derive(Copy, Clone)]
  92. pub struct OctalPermissions {
  93. pub permissions: Permissions,
  94. }
  95. /// A file’s number of hard links on the filesystem.
  96. ///
  97. /// Under Unix, a file can exist on the filesystem only once but appear in
  98. /// multiple directories. However, it’s rare (but occasionally useful!) for a
  99. /// regular file to have a link count greater than 1, so we highlight the
  100. /// block count specifically for this case.
  101. #[derive(Copy, Clone)]
  102. pub struct Links {
  103. /// The actual link count.
  104. pub count: nlink_t,
  105. /// Whether this file is a regular file with more than one hard link.
  106. pub multiple: bool,
  107. }
  108. /// A file’s inode. Every directory entry on a Unix filesystem has an inode,
  109. /// including directories and links, so this is applicable to everything exa
  110. /// can deal with.
  111. #[derive(Copy, Clone)]
  112. pub struct Inode(pub ino_t);
  113. /// The number of blocks that a file takes up on the filesystem, if any.
  114. #[derive(Copy, Clone)]
  115. pub enum Blocks {
  116. /// This file has the given number of blocks.
  117. Some(blkcnt_t),
  118. /// This file isn’t of a type that can take up blocks.
  119. None,
  120. }
  121. /// The ID of the user that owns a file. This will only ever be a number;
  122. /// looking up the username is done in the `display` module.
  123. #[derive(Copy, Clone)]
  124. pub struct User(pub uid_t);
  125. /// The ID of the group that a file belongs to.
  126. #[derive(Copy, Clone)]
  127. pub struct Group(pub gid_t);
  128. /// A file’s size, in bytes. This is usually formatted by the `number_prefix`
  129. /// crate into something human-readable.
  130. #[derive(Copy, Clone)]
  131. pub enum Size {
  132. /// This file has a defined size.
  133. Some(u64),
  134. /// This file has no size, or has a size but we aren’t interested in it.
  135. ///
  136. /// Under Unix, directory entries that aren’t regular files will still
  137. /// have a file size. For example, a directory will just contain a list of
  138. /// its files as its “contents” and will be specially flagged as being a
  139. /// directory, rather than a file. However, seeing the “file size” of this
  140. /// data is rarely useful — I can’t think of a time when I’ve seen it and
  141. /// learnt something. So we discard it and just output “-” instead.
  142. ///
  143. /// See this answer for more: <https://unix.stackexchange.com/a/68266>
  144. None,
  145. /// This file is a block or character device, so instead of a size, print
  146. /// out the file’s major and minor device IDs.
  147. ///
  148. /// This is what ls does as well. Without it, the devices will just have
  149. /// file sizes of zero.
  150. DeviceIDs(DeviceIDs),
  151. }
  152. /// The major and minor device IDs that gets displayed for device files.
  153. ///
  154. /// You can see what these device numbers mean:
  155. /// - <http://www.lanana.org/docs/device-list/>
  156. /// - <http://www.lanana.org/docs/device-list/devices-2.6+.txt>
  157. #[derive(Copy, Clone)]
  158. pub struct DeviceIDs {
  159. pub major: u8,
  160. pub minor: u8,
  161. }
  162. /// One of a file’s timestamps (created, accessed, or modified).
  163. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
  164. pub struct Time {
  165. pub seconds: time_t,
  166. pub nanoseconds: time_t,
  167. }
  168. /// A file’s status in a Git repository. Whether a file is in a repository or
  169. /// not is handled by the Git module, rather than having a “null” variant in
  170. /// this enum.
  171. #[derive(PartialEq, Eq, Copy, Clone)]
  172. pub enum GitStatus {
  173. /// This file hasn’t changed since the last commit.
  174. NotModified,
  175. /// This file didn’t exist for the last commit, and is not specified in
  176. /// the ignored files list.
  177. New,
  178. /// A file that’s been modified since the last commit.
  179. Modified,
  180. /// A deleted file. This can’t ever be shown, but it’s here anyway!
  181. Deleted,
  182. /// A file that Git has tracked a rename for.
  183. Renamed,
  184. /// A file that’s had its type (such as the file permissions) changed.
  185. TypeChange,
  186. /// A file that’s ignored (that matches a line in .gitignore)
  187. Ignored,
  188. /// A file that’s updated but unmerged.
  189. Conflicted,
  190. }
  191. /// A file’s complete Git status. It’s possible to make changes to a file, add
  192. /// it to the staging area, then make *more* changes, so we need to list each
  193. /// file’s status for both of these.
  194. #[derive(Copy, Clone)]
  195. pub struct Git {
  196. pub staged: GitStatus,
  197. pub unstaged: GitStatus,
  198. }
  199. impl Default for Git {
  200. /// Create a Git status for a file with nothing done to it.
  201. fn default() -> Self {
  202. Self {
  203. staged: GitStatus::NotModified,
  204. unstaged: GitStatus::NotModified,
  205. }
  206. }
  207. }
  208. pub enum SecurityContextType<'a> {
  209. SELinux(&'a str),
  210. None
  211. }
  212. pub struct SecurityContext<'a> {
  213. pub context: SecurityContextType<'a>,
  214. }
  215. #[allow(dead_code)]
  216. #[derive(PartialEq, Copy, Clone)]
  217. pub enum SubdirGitRepoStatus{
  218. NoRepo,
  219. GitClean,
  220. GitDirty,
  221. GitUnknown
  222. }
  223. #[derive(Clone)]
  224. pub struct SubdirGitRepo{
  225. pub status : SubdirGitRepoStatus,
  226. pub branch : Option<String>
  227. }
  228. impl Default for SubdirGitRepo{
  229. fn default() -> Self {
  230. Self{
  231. status : SubdirGitRepoStatus::NoRepo,
  232. branch : None
  233. }
  234. }
  235. }