| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- // SPDX-FileCopyrightText: 2024 Christina SĆørensen
- // SPDX-License-Identifier: EUPL-1.2
- //
- // SPDX-FileCopyrightText: 2023-2024 Christina SĆørensen, eza contributors
- // SPDX-FileCopyrightText: 2014 Benjamin Sago
- // SPDX-License-Identifier: MIT
- //! Wrapper types for the values returned from `File`s.
- //!
- //! The methods of `File` that return information about the entry on the
- //! filesystem -- size, modification date, block count, or Git status -- used
- //! to just return these as formatted strings, but this became inflexible once
- //! customisable output styles landed.
- //!
- //! Instead, they will return a wrapper type from this module, which tags the
- //! type with what field it is while containing the actual raw value.
- //!
- //! The `output::details` module, among others, uses these types to render and
- //! display the information as formatted strings.
- #![allow(non_camel_case_types)]
- #![allow(clippy::struct_excessive_bools)]
- /// The type of a fileās group ID.
- #[cfg(unix)]
- pub type gid_t = u32;
- /// The type of a fileās inode.
- #[cfg(unix)]
- pub type ino_t = u64;
- /// The type of a fileās number of links.
- #[cfg(unix)]
- pub type nlink_t = u64;
- /// The type of a fileās user ID.
- #[cfg(unix)]
- pub type uid_t = u32;
- /// The type of user file flags
- pub type flag_t = u32;
- /// The fileās base type, which gets displayed in the very first column of the
- /// details output.
- ///
- /// This type is set entirely by the filesystem, rather than relying on a
- /// fileās contents. So ālinkā is a type, but āimageā is just a type of
- /// regular file. (See the `filetype` module for those checks.)
- ///
- /// Its ordering is used when sorting by type.
- #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
- pub enum Type {
- Directory,
- File,
- Link,
- Pipe,
- Socket,
- CharDevice,
- BlockDevice,
- Special,
- }
- impl Type {
- #[must_use]
- pub fn is_regular_file(self) -> bool {
- matches!(self, Self::File)
- }
- }
- /// The fileās Unix permission bitfield, with one entry per bit.
- #[derive(Copy, Clone)]
- #[rustfmt::skip]
- #[cfg(unix)]
- pub struct Permissions {
- pub user_read: bool,
- pub user_write: bool,
- pub user_execute: bool,
- pub group_read: bool,
- pub group_write: bool,
- pub group_execute: bool,
- pub other_read: bool,
- pub other_write: bool,
- pub other_execute: bool,
- pub sticky: bool,
- pub setgid: bool,
- pub setuid: bool,
- }
- /// The file's `FileAttributes` field, available only on Windows.
- #[derive(Copy, Clone)]
- #[rustfmt::skip]
- #[cfg(windows)]
- pub struct Attributes {
- pub archive: bool,
- pub directory: bool,
- pub readonly: bool,
- pub hidden: bool,
- pub system: bool,
- pub reparse_point: bool,
- }
- /// The three pieces of information that are displayed as a single column in
- /// the details view. These values are fused together to make the output a
- /// little more compressed.
- #[derive(Copy, Clone)]
- pub struct PermissionsPlus {
- #[allow(unused)]
- pub file_type: Type,
- #[cfg(unix)]
- pub permissions: Permissions,
- #[cfg(windows)]
- pub attributes: Attributes,
- #[allow(unused)]
- pub xattrs: bool,
- }
- /// The permissions encoded as octal values
- #[derive(Copy, Clone)]
- #[cfg(unix)]
- pub struct OctalPermissions {
- pub permissions: Permissions,
- }
- /// A fileās number of hard links on the filesystem.
- ///
- /// Under Unix, a file can exist on the filesystem only once but appear in
- /// multiple directories. However, itās rare (but occasionally useful!) for a
- /// regular file to have a link count greater than 1, so we highlight the
- /// block count specifically for this case.
- #[cfg(unix)]
- #[derive(Copy, Clone)]
- pub struct Links {
- /// The actual link count.
- pub count: nlink_t,
- /// Whether this file is a regular file with more than one hard link.
- pub multiple: bool,
- }
- /// A fileās inode. Every directory entry on a Unix filesystem has an inode,
- /// including directories and links, so this is applicable to everything exa
- /// can deal with.
- #[cfg(unix)]
- #[derive(Copy, Clone)]
- pub struct Inode(pub ino_t);
- /// A file's size of allocated file system blocks.
- #[derive(Copy, Clone)]
- #[cfg(unix)]
- pub enum Blocksize {
- /// This file has the given number of blocks.
- Some(u64),
- /// This file isnāt of a type that can take up blocks.
- None,
- }
- /// The ID of the user that owns a file. This will only ever be a number;
- /// looking up the username is done in the `display` module.
- #[cfg(unix)]
- #[derive(Copy, Clone)]
- pub struct User(pub uid_t);
- /// The ID of the group that a file belongs to.
- #[cfg(unix)]
- #[derive(Copy, Clone)]
- pub struct Group(pub gid_t);
- /// A fileās size, in bytes. This is usually formatted by the `unit_prefix`
- /// crate into something human-readable.
- #[derive(Copy, Clone)]
- pub enum Size {
- /// This file has a defined size.
- Some(u64),
- /// This file has no size, or has a size but we arenāt interested in it.
- ///
- /// Under Unix, directory entries that arenāt regular files will still
- /// have a file size. For example, a directory will just contain a list of
- /// its files as its ācontentsā and will be specially flagged as being a
- /// directory, rather than a file. However, seeing the āfile sizeā of this
- /// data is rarely useful ā I canāt think of a time when Iāve seen it and
- /// learnt something. So we discard it and just output ā-ā instead.
- ///
- /// See this answer for more: <https://unix.stackexchange.com/a/68266>
- None,
- /// This file is a block or character device, so instead of a size, print
- /// out the fileās major and minor device IDs.
- ///
- /// This is what ls does as well. Without it, the devices will just have
- /// file sizes of zero.
- DeviceIDs(DeviceIDs),
- }
- /// The major and minor device IDs that gets displayed for device files.
- ///
- /// You can see what these device numbers mean:
- /// - <http://www.lanana.org/docs/device-list/>
- /// - <http://www.lanana.org/docs/device-list/devices-2.6+.txt>
- #[derive(Copy, Clone)]
- pub struct DeviceIDs {
- pub major: u32,
- pub minor: u32,
- }
- /// A fileās status in a Git repository. Whether a file is in a repository or
- /// not is handled by the Git module, rather than having a ānullā variant in
- /// this enum.
- #[derive(PartialEq, Eq, Copy, Clone)]
- pub enum GitStatus {
- /// This file hasnāt changed since the last commit.
- NotModified,
- /// This file didnāt exist for the last commit, and is not specified in
- /// the ignored files list.
- New,
- /// A file thatās been modified since the last commit.
- Modified,
- /// A deleted file. This canāt ever be shown, but itās here anyway!
- Deleted,
- /// A file that Git has tracked a rename for.
- Renamed,
- /// A file thatās had its type (such as the file permissions) changed.
- TypeChange,
- /// A file thatās ignored (that matches a line in .gitignore)
- Ignored,
- /// A file thatās updated but unmerged.
- Conflicted,
- }
- /// A fileās complete Git status. Itās possible to make changes to a file, add
- /// it to the staging area, then make *more* changes, so we need to list each
- /// fileās status for both of these.
- #[derive(Copy, Clone)]
- pub struct Git {
- pub staged: GitStatus,
- pub unstaged: GitStatus,
- }
- impl Default for Git {
- /// Create a Git status for a file with nothing done to it.
- fn default() -> Self {
- Self {
- staged: GitStatus::NotModified,
- unstaged: GitStatus::NotModified,
- }
- }
- }
- pub enum SecurityContextType<'a> {
- SELinux(&'a str),
- None,
- }
- pub struct SecurityContext<'a> {
- pub context: SecurityContextType<'a>,
- }
- #[allow(dead_code)]
- #[derive(PartialEq, Copy, Clone)]
- pub enum SubdirGitRepoStatus {
- NoRepo,
- GitClean,
- GitDirty,
- }
- #[derive(Clone)]
- pub struct SubdirGitRepo {
- pub status: Option<SubdirGitRepoStatus>,
- pub branch: Option<String>,
- }
- impl Default for SubdirGitRepo {
- fn default() -> Self {
- Self {
- status: Some(SubdirGitRepoStatus::NoRepo),
- branch: None,
- }
- }
- }
- /// The user file flags on the file. This will only ever be a number;
- /// looking up the flags is done in the `display` module.
- pub struct Flags(pub flag_t);
|