use bun_core::Mode;
use bun_core::ZBox;
pub use super::file::File;
pub use super::PosixStat;
#[inline]
fn path_to_zbox(path: &str) -> ZBox {
ZBox::from_bytes(path.as_bytes())
}
pub fn read_to_string(path: &str) -> Result<String, std::io::Error> {
let zpath = path_to_zbox(path);
let file = File::open(zpath.as_zstr(), libc::O_RDONLY | libc::O_CLOEXEC, 0)
.map_err(|e| std::io::Error::from_raw_os_error(e.errno as i32))?;
let bytes = file
.read_to_end()
.map_err(|e| std::io::Error::from_raw_os_error(e.errno as i32))?;
String::from_utf8(bytes).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
}
pub fn read(path: &str) -> Result<Vec<u8>, std::io::Error> {
let zpath = path_to_zbox(path);
let file = File::open(zpath.as_zstr(), libc::O_RDONLY | libc::O_CLOEXEC, 0)
.map_err(|e| std::io::Error::from_raw_os_error(e.errno as i32))?;
file.read_to_end()
.map_err(|e| std::io::Error::from_raw_os_error(e.errno as i32))
}
pub fn write(path: &str, data: &[u8]) -> Result<(), std::io::Error> {
let zpath = path_to_zbox(path);
let file = File::open(
zpath.as_zstr(),
libc::O_WRONLY | libc::O_CREAT | libc::O_TRUNC | libc::O_CLOEXEC,
0o666 as Mode,
)
.map_err(|e| std::io::Error::from_raw_os_error(e.errno as i32))?;
file.write_all(data)
.map_err(|e| std::io::Error::from_raw_os_error(e.errno as i32))
}
pub fn metadata(path: &str) -> Result<PosixStat, std::io::Error> {
let zpath = path_to_zbox(path);
super::stat(zpath.as_zstr())
.map(|s| PosixStat::init(&s))
.map_err(|e| std::io::Error::from_raw_os_error(e.errno as i32))
}
#[derive(Debug, Clone)]
pub struct OpenOptions {
read: bool,
write: bool,
append: bool,
truncate: bool,
create: bool,
create_new: bool,
mode: Mode,
}
impl OpenOptions {
pub fn new() -> Self {
OpenOptions {
read: false,
write: false,
append: false,
truncate: false,
create: false,
create_new: false,
mode: 0o666 as Mode,
}
}
pub fn read(&mut self, read: bool) -> &mut Self {
self.read = read;
self
}
pub fn write(&mut self, write: bool) -> &mut Self {
self.write = write;
self
}
pub fn append(&mut self, append: bool) -> &mut Self {
self.append = append;
self
}
pub fn truncate(&mut self, truncate: bool) -> &mut Self {
self.truncate = truncate;
self
}
pub fn create(&mut self, create: bool) -> &mut Self {
self.create = create;
self
}
pub fn create_new(&mut self, create_new: bool) -> &mut Self {
self.create_new = create_new;
self
}
pub fn mode(&mut self, mode: Mode) -> &mut Self {
self.mode = mode;
self
}
pub fn open(&self, path: &str) -> Result<File, std::io::Error> {
let mut flags = libc::O_CLOEXEC;
if self.append {
flags |= libc::O_APPEND;
}
if self.truncate {
flags |= libc::O_TRUNC;
}
if self.create_new {
flags |= libc::O_CREAT | libc::O_EXCL;
} else if self.create {
flags |= libc::O_CREAT;
}
match (self.read, self.write, self.append) {
(false, false, false) => flags |= libc::O_RDONLY,
(true, false, false) => flags |= libc::O_RDONLY,
(false, true, false) => flags |= libc::O_WRONLY,
(true, true, false) => flags |= libc::O_RDWR,
(false, _, true) => flags |= libc::O_WRONLY,
(true, _, true) => flags |= libc::O_RDWR,
}
let zpath = path_to_zbox(path);
File::open(zpath.as_zstr(), flags, self.mode)
.map_err(|e| std::io::Error::from_raw_os_error(e.errno as i32))
}
}
impl Default for OpenOptions {
fn default() -> Self {
Self::new()
}
}