use bitflags::bitflags;
bitflags! {
pub struct Mode: u32 {
const DIR = 0o040000;
const FILE = 0o100644;
const FILE_EXECUTABLE = 0o100755;
const SYMLINK = 0o120000;
const COMMIT = 0o160000;
}
}
pub(crate) mod mode {
impl super::Mode {
pub fn is_sparse(&self) -> bool {
*self == Self::DIR
}
}
}
pub(crate) mod at_rest {
use bitflags::bitflags;
bitflags! {
pub struct Flags: u16 {
const PATH_LEN = 0x0fff;
const STAGE_MASK = 0x3000;
const EXTENDED = 0x4000;
const ASSUME_VALID = 0x8000;
}
}
bitflags! {
pub struct FlagsExtended: u16 {
const INTENT_TO_ADD = 1 << (29 - 16);
const SKIP_WORKTREE = 1 << (30 - 16);
}
}
impl FlagsExtended {
pub fn to_flags(self) -> Option<super::Flags> {
super::Flags::from_bits((self.bits as u32) << 16)
}
}
impl Flags {
pub fn to_memory(self) -> super::Flags {
super::Flags::from_bits((self & (Flags::PATH_LEN | Flags::STAGE_MASK | Flags::ASSUME_VALID)).bits as u32)
.expect("PATHLEN is part of memory representation")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn flags_from_bits_with_conflict() {
let input = 0b1110_0010_1000_1011;
assert_eq!(Flags::from_bits(input).unwrap().bits, input);
}
}
}
bitflags! {
pub struct Flags: u32 {
const STAGE_MASK = 0x3000;
const PATH_LEN = 0x0fff;
const ASSUME_VALID = 1 << 15;
const UPDATE = 1 << 16;
const REMOVE = 1 << 17;
const UPTODATE = 1 << 18;
const ADDED = 1 << 19;
const HASHED = 1 << 20;
const FSMONITOR_VALID = 1 << 21;
const WORKTREE_REMOVE = 1 << 22;
const CONFLICTED = 1 << 23;
const UNPACKED = 1 << 24;
const NEW_SKIP_WORKTREE = 1 << 25;
const PATHSPEC_MATCHED = 1 << 26;
const UPDATE_IN_BASE = 1 << 27;
const STRIP_NAME = 1 << 28;
const INTENT_TO_ADD = 1 << 29; const SKIP_WORKTREE = 1 << 30; }
}
impl Flags {
pub fn stage(&self) -> u32 {
(*self & Flags::STAGE_MASK).bits >> 12
}
}
#[derive(PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Copy)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct Time {
pub secs: u32,
pub nsecs: u32,
}
#[derive(PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Copy)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct Stat {
pub mtime: Time,
pub ctime: Time,
pub dev: u32,
pub ino: u32,
pub uid: u32,
pub gid: u32,
pub size: u32,
}
mod access {
use bstr::{BStr, ByteSlice};
use crate::{Entry, State};
impl Entry {
pub fn path<'a>(&self, state: &'a State) -> &'a BStr {
(&state.path_backing[self.path.clone()]).as_bstr()
}
pub fn path_in<'backing>(&self, backing: &'backing crate::PathStorageRef) -> &'backing BStr {
(backing[self.path.clone()]).as_bstr()
}
pub fn stage(&self) -> u32 {
self.flags.stage()
}
}
}
mod _impls {
use std::cmp::Ordering;
use crate::{Entry, State};
impl Entry {
pub fn cmp(&self, other: &Self, state: &State) -> Ordering {
let lhs = self.path(state);
let rhs = other.path(state);
let common_len = lhs.len().min(rhs.len());
lhs[..common_len]
.cmp(&rhs[..common_len])
.then_with(|| lhs.len().cmp(&rhs.len()))
.then_with(|| self.stage().cmp(&other.stage()))
}
}
}