use crate::{Stat, Timespec};
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PosixStat {
pub dev: u64,
pub ino: u64,
pub mode: u64,
pub nlink: u64,
pub uid: u64,
pub gid: u64,
pub rdev: u64,
pub size: u64,
pub blksize: u64,
pub blocks: u64,
pub atim: Timespec,
pub mtim: Timespec,
pub ctim: Timespec,
pub birthtim: Timespec,
}
unsafe impl bun_core::ffi::Zeroable for PosixStat {}
#[cfg(not(windows))]
mod to_u64_impl {
pub(super) trait ToU64: Copy {
fn to_u64(self) -> u64;
}
macro_rules! impl_to_u64_signed {
($($t:ty),*) => {$(
impl ToU64 for $t {
#[inline]
fn to_u64(self) -> u64 {
self as i64 as u64
}
}
)*};
}
macro_rules! impl_to_u64_unsigned {
($($t:ty),*) => {$(
impl ToU64 for $t {
#[inline]
fn to_u64(self) -> u64 { self as u64 }
}
)*};
}
impl_to_u64_signed!(i8, i16, i32, i64, isize);
impl_to_u64_unsigned!(u8, u16, u32, u64, usize);
}
#[cfg(not(windows))]
#[inline]
fn to_u64<T: to_u64_impl::ToU64>(value: T) -> u64 {
to_u64_impl::ToU64::to_u64(value)
}
#[inline]
pub fn stat_atime(s: &Stat) -> Timespec {
#[cfg(unix)]
{
Timespec {
sec: s.st_atime,
nsec: s.st_atime_nsec,
}
}
#[cfg(windows)]
{
Timespec {
sec: s.atim.sec as i64,
nsec: s.atim.nsec as i64,
}
}
}
#[inline]
pub fn stat_mtime(s: &Stat) -> Timespec {
#[cfg(unix)]
{
Timespec {
sec: s.st_mtime,
nsec: s.st_mtime_nsec,
}
}
#[cfg(windows)]
{
Timespec {
sec: s.mtim.sec as i64,
nsec: s.mtim.nsec as i64,
}
}
}
#[inline]
pub fn stat_ctime(s: &Stat) -> Timespec {
#[cfg(unix)]
{
Timespec {
sec: s.st_ctime,
nsec: s.st_ctime_nsec,
}
}
#[cfg(windows)]
{
Timespec {
sec: s.ctim.sec as i64,
nsec: s.ctim.nsec as i64,
}
}
}
#[inline]
pub fn stat_birthtime(s: &Stat) -> Timespec {
#[cfg(windows)]
{
Timespec {
sec: s.birthtim.sec as i64,
nsec: s.birthtim.nsec as i64,
}
}
#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
{
Timespec {
sec: s.st_birthtime as i64,
nsec: s.st_birthtime_nsec as i64,
}
}
#[cfg(not(any(
windows,
target_os = "macos",
target_os = "ios",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)))]
{
let _ = s;
Timespec::EPOCH
}
}
impl PosixStat {
pub fn init(stat_: &Stat) -> PosixStat {
let atime_val = stat_atime(stat_);
let mtime_val = stat_mtime(stat_);
let ctime_val = stat_ctime(stat_);
let birthtime_val = stat_birthtime(stat_);
#[cfg(unix)]
{
PosixStat {
dev: to_u64(stat_.st_dev),
ino: to_u64(stat_.st_ino),
mode: to_u64(stat_.st_mode),
nlink: to_u64(stat_.st_nlink),
uid: to_u64(stat_.st_uid),
gid: to_u64(stat_.st_gid),
rdev: to_u64(stat_.st_rdev),
size: to_u64(stat_.st_size),
blksize: to_u64(stat_.st_blksize),
blocks: to_u64(stat_.st_blocks),
atim: atime_val,
mtim: mtime_val,
ctim: ctime_val,
birthtim: birthtime_val,
}
}
#[cfg(windows)]
{
PosixStat {
dev: stat_.st_dev,
ino: stat_.st_ino,
mode: stat_.st_mode,
nlink: stat_.st_nlink,
uid: stat_.st_uid,
gid: stat_.st_gid,
rdev: stat_.st_rdev,
size: stat_.st_size,
blksize: stat_.st_blksize,
blocks: stat_.st_blocks,
atim: atime_val,
mtim: mtime_val,
ctim: ctime_val,
birthtim: birthtime_val,
}
}
}
pub fn atime(&self) -> Timespec {
self.atim
}
pub fn mtime(&self) -> Timespec {
self.mtim
}
pub fn ctime(&self) -> Timespec {
self.ctim
}
pub fn birthtime(&self) -> Timespec {
self.birthtim
}
}