use cmd::{Cmd, CmdKind};
use core::mem::uninitialized;
use drone_core::ffi::CStr;
use drone_core::fs::OpenOptions;
use drone_fatfs_raw::{
FA_CREATE_ALWAYS, FA_CREATE_NEW, FA_OPEN_ALWAYS, FA_OPEN_APPEND, FA_READ,
FA_WRITE, FIL,
};
use fat_sess::{FatSess, FatSessError, FatSessRes};
use file_sess::FileSess;
use futures::prelude::*;
pub struct File {
fil: Box<FIL>,
}
unsafe impl Send for File {}
impl File {
pub(crate) unsafe fn new_uninitialized() -> Self {
let fil = Box::new(uninitialized());
Self { fil }
}
pub(crate) fn as_raw_mut(&mut self) -> *mut FIL {
self.fil.as_mut()
}
pub fn sess<'sess, T: FatSessRes>(
&'sess mut self,
fat_sess: &'sess mut FatSess<T>,
) -> FileSess<T> {
FileSess::new(self, fat_sess)
}
}
pub struct FileOptions<'sess, T: FatSessRes> {
fat_sess: &'sess mut FatSess<T>,
mode: u8,
}
impl<'sess, T: FatSessRes> FileOptions<'sess, T> {
pub(crate) fn new(fat_sess: &'sess mut FatSess<T>) -> Self {
Self { fat_sess, mode: 0 }
}
pub fn open(
self,
path: &'sess CStr,
) -> impl Future<Item = File, Error = FatSessError<T::Error>> + 'sess {
let Self { fat_sess, mode } = self;
unsafe { fat_sess.cmd(Cmd(CmdKind::Open(path, mode)), |res| res.open) }
}
}
impl<'sess, T: FatSessRes> OpenOptions for FileOptions<'sess, T> {
fn read(mut self, read: bool) -> Self {
if read {
self.mode |= FA_READ as u8;
} else {
self.mode &= !(FA_READ as u8);
}
self
}
fn write(mut self, write: bool) -> Self {
if write {
self.mode |= FA_WRITE as u8;
} else {
self.mode &= !(FA_WRITE as u8);
}
self
}
fn append(mut self, append: bool) -> Self {
if append {
self.mode |= FA_OPEN_APPEND as u8;
} else {
self.mode &= !(FA_OPEN_APPEND as u8);
}
self
}
fn truncate(mut self, truncate: bool) -> Self {
if truncate {
self.mode |= FA_CREATE_ALWAYS as u8;
} else {
self.mode &= !(FA_CREATE_ALWAYS as u8);
}
self
}
fn create(mut self, create: bool) -> Self {
if create {
self.mode |= FA_OPEN_ALWAYS as u8;
} else {
self.mode &= !(FA_OPEN_ALWAYS as u8);
}
self
}
fn create_new(mut self, create_new: bool) -> Self {
if create_new {
self.mode |= FA_CREATE_NEW as u8;
} else {
self.mode &= !(FA_CREATE_NEW as u8);
}
self
}
}