use core::ffi::c_uint;
use alloc::vec::Vec;
use sys::ffi::FileOptions;
use sys::ffi::SDFile;
use sys::traits::AsRaw;
use crate::api;
use crate::Path;
use crate::ApiError;
use crate::error::Error;
use crate::options::FileOptionsExt;
use crate::options::OpenOptions;
use crate::seek::SeekFrom;
pub trait AnyFile: AsRaw<Type = SDFile> {}
impl<T: AsRaw<Type = SDFile>> AnyFile for T {}
#[must_use = "File will be closed on drop"]
#[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
pub struct File<Api: api::Api = api::Default>(pub(crate) *mut SDFile, pub(crate) Api);
impl<Api: api::Api> AsRaw for File<Api> {
type Type = SDFile;
unsafe fn as_raw(&self) -> *mut Self::Type { self.0 }
}
impl File<api::Default> {
#[must_use]
pub fn options() -> impl OpenOptions + FileOptionsExt { FileOptions::new() }
}
impl<Api: api::Api> File<Api> {
#[doc(alias = "sys::ffi::playdate_file::open")]
#[must_use]
pub fn open<P: AsRef<Path>>(path: P, data_dir: bool) -> Result<File<Api>, ApiError>
where Api: Default {
let api = Default::default();
crate::ops::open(api, path, FileOptions::new().read(true).read_data(data_dir))
}
#[doc(alias = "sys::ffi::playdate_file::open")]
#[must_use]
pub fn open_with<P: AsRef<Path>>(api: Api, path: P, data_dir: bool) -> Result<File<Api>, ApiError> {
crate::ops::open(api, path, FileOptions::new().read(true).read_data(data_dir))
}
#[doc(alias = "sys::ffi::playdate_file::read")]
#[must_use]
#[inline(always)]
pub fn read(&mut self, to: &mut Vec<u8>, len: c_uint) -> Result<c_uint, Error> {
crate::ops::read(self, to, len)
}
#[doc(alias = "sys::ffi::playdate_file::write")]
#[must_use]
#[inline(always)]
pub fn write(&mut self, from: &[u8]) -> Result<c_uint, Error> { crate::ops::write(self, from) }
#[doc(alias = "sys::ffi::playdate_file::flush")]
#[inline(always)]
pub fn flush(&mut self) -> Result<c_uint, Error> { crate::ops::flush(self) }
#[doc(alias = "sys::ffi::playdate_file::tell")]
#[must_use]
#[inline(always)]
pub fn tell(&mut self) -> Result<c_uint, Error> { crate::ops::tell(self) }
#[doc(alias = "sys::ffi::playdate_file::seek")]
#[inline(always)]
pub fn seek(&mut self, pos: SeekFrom) -> Result<(), Error> {
let (whence, pos) = pos.into_parts();
crate::ops::seek(self, pos, whence)
}
#[doc(alias = "sys::ffi::playdate_file::close")]
#[inline(always)]
pub fn close(self) -> Result<(), Error> { crate::ops::close(self) }
}
impl<Api: api::Api> Drop for File<Api> {
fn drop(&mut self) {
if !self.0.is_null() {
let f = self.1.close();
let result = unsafe { f(self.0) };
self.0 = core::ptr::null_mut();
match Error::ok_from_code_with(result, &self.1) {
Ok(_) => (),
Err(err) => println!("Err on file-drop: {err}"),
}
}
}
}