playdate_fs/
error.rs

1use alloc::borrow::ToOwned;
2use core::ffi::c_int;
3use core::ffi::c_uint;
4use core::fmt;
5use sys::ffi::CStr;
6use sys::ffi::CString;
7
8
9pub type ApiError = sys::error::Error<self::Error>;
10
11
12#[derive(Debug)]
13pub enum Error {
14	Fs(CString),
15	Unknown,
16}
17
18impl fmt::Display for Error {
19	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20		match &self {
21			Error::Fs(cs) => {
22				match cs.to_str() {
23					Ok(err) => err.fmt(f),
24					Err(_) => f.write_fmt(format_args!("Fs: {cs:?}")),
25				}
26			},
27			Error::Unknown => write!(f, "Fs: unknown error"),
28		}
29	}
30}
31
32
33impl From<Error> for ApiError {
34	fn from(err: Error) -> Self { ApiError::Api(err) }
35}
36
37impl From<&'_ CStr> for Error {
38	fn from(cs: &CStr) -> Self { Self::Fs(cs.to_owned()) }
39}
40
41
42impl core::error::Error for Error {}
43
44
45impl Error {
46	/// Equivalent to [`sys::ffi::playdate_file::geterr`]
47	#[doc(alias = "sys::ffi::playdate_file::geterr")]
48	#[must_use = "Error message is borrowed from C part, must be used immediately or converted to owned string."]
49	pub fn latest() -> Option<Self> {
50		use crate::api::Api;
51		let f = crate::api::Default.geterr();
52		let ptr = unsafe { f() };
53		Self::from_ptr(ptr)
54	}
55
56	/// Equivalent to [`sys::ffi::playdate_file::geterr`]
57	#[doc(alias = "sys::ffi::playdate_file::geterr")]
58	#[must_use = "Error message is borrowed from C part, must be used immediately or converted to owned string."]
59	pub fn latest_with<Api: crate::api::Api>(api: Api) -> Option<Self> {
60		let f = api.geterr();
61		let ptr = unsafe { f() };
62		Self::from_ptr(ptr)
63	}
64
65	#[must_use = "Error message is borrowed from C part, must be used immediately or converted to owned string."]
66	pub fn from_ptr(ptr: *const core::ffi::c_char) -> Option<Self> {
67		if ptr.is_null() {
68			None
69		} else {
70			Self::from(unsafe { CStr::from_ptr(ptr as _) }).into()
71		}
72	}
73
74	#[must_use = "Error message is borrowed from C part, must be used immediately or converted to owned string."]
75	#[inline(always)]
76	pub fn ok_from_code(result: c_int) -> Result<c_uint, Self> {
77		if result < 0 {
78			Err(Self::latest().unwrap_or(Self::Unknown))
79		} else {
80			Ok(result as c_uint)
81		}
82	}
83
84	#[must_use = "Error message is borrowed from C part, must be used immediately or converted to owned string."]
85	#[inline(always)]
86	pub fn ok_from_code_with<Api: crate::api::Api>(result: c_int, api: Api) -> Result<c_uint, Self> {
87		if result < 0 {
88			Err(Self::latest_with(api).unwrap_or(Self::Unknown))
89		} else {
90			Ok(result as c_uint)
91		}
92	}
93}