use std::ffi::CStr;
use std::fs::File;
use std::io;
use crate::dir::{clone_dirfd_upgrade, to_cstr};
use crate::{AsPath, Dir};
#[derive(Copy, Clone)]
pub struct DirFlags {
flags: libc::c_int,
}
impl DirFlags {
#[inline]
pub(crate) fn new(flags: libc::c_int) -> DirFlags {
DirFlags { flags }
}
#[inline]
pub fn with(self, flags: libc::c_int) -> DirFlags {
DirFlags {
flags: self.flags | flags,
}
}
#[inline]
pub fn without(self, flags: libc::c_int) -> DirFlags {
DirFlags {
flags: self.flags & !flags,
}
}
#[inline]
pub fn get_flags(&self) -> libc::c_int {
self.flags
}
#[inline]
pub fn open<P: AsPath>(&self, path: P) -> io::Result<Dir> {
Dir::_open(to_cstr(path)?.as_ref(), self.flags)
}
}
#[derive(Copy, Clone)]
pub struct DirMethodFlags<'a> {
object: &'a Dir,
flags: libc::c_int,
}
impl<'a> DirMethodFlags<'a> {
#[inline]
pub(crate) fn new(object: &'a Dir, flags: libc::c_int) -> Self {
Self { object, flags }
}
#[inline]
pub fn with(self, flags: libc::c_int) -> Self {
Self {
object: self.object,
flags: self.flags | flags,
}
}
#[inline]
pub fn without(self, flags: libc::c_int) -> Self {
Self {
object: self.object,
flags: self.flags & !flags,
}
}
#[inline]
pub fn sub_dir<P: AsPath>(&self, path: P) -> io::Result<Dir> {
self.object._sub_dir(to_cstr(path)?.as_ref(), self.flags)
}
#[inline]
pub fn open_file<P: AsPath>(&self, path: P) -> io::Result<File> {
self.object
._open_file(to_cstr(path)?.as_ref(), self.flags | libc::O_RDONLY, 0)
}
#[inline]
pub fn write_file<P: AsPath>(&self, path: P, mode: libc::mode_t) -> io::Result<File> {
self.object._open_file(
to_cstr(path)?.as_ref(),
self.flags | libc::O_CREAT | libc::O_WRONLY | libc::O_TRUNC,
mode,
)
}
#[inline]
pub fn append_file<P: AsPath>(&self, path: P, mode: libc::mode_t) -> io::Result<File> {
self.object._open_file(
to_cstr(path)?.as_ref(),
self.flags | libc::O_CREAT | libc::O_WRONLY | libc::O_APPEND,
mode,
)
}
#[cfg(feature = "o_tmpfile")]
#[inline]
pub fn new_unnamed_file(&self, mode: libc::mode_t) -> io::Result<File> {
self.object._open_file(
unsafe { CStr::from_bytes_with_nul_unchecked(b".\0") },
self.flags | libc::O_TMPFILE | libc::O_WRONLY,
mode,
)
}
#[inline]
pub fn new_file<P: AsPath>(&self, path: P, mode: libc::mode_t) -> io::Result<File> {
self.object._open_file(
to_cstr(path)?.as_ref(),
self.flags | libc::O_CREAT | libc::O_EXCL | libc::O_WRONLY,
mode,
)
}
pub fn clone_upgrade(&self) -> io::Result<Dir> {
Ok(Dir::new(clone_dirfd_upgrade(
self.object.rawfd(),
self.flags,
)?))
}
}