diff --git a/ctru-rs/src/error.rs b/ctru-rs/src/error.rs index b1d968b..53c3fbe 100644 --- a/ctru-rs/src/error.rs +++ b/ctru-rs/src/error.rs @@ -1,15 +1,18 @@ use std::error; use std::fmt; +use ctru_sys::result::{R_DESCRIPTION, R_LEVEL, R_MODULE, R_SUMMARY}; + pub type Result = ::std::result::Result; /// The error type returned by all libctru functions. +#[non_exhaustive] pub enum Error { - Os(i32), + Os(ctru_sys::Result), } -impl From for Error { - fn from(err: i32) -> Self { +impl From for Error { + fn from(err: ctru_sys::Result) -> Self { Error::Os(err) } } @@ -17,12 +20,21 @@ impl From for Error { impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Error::Os(err) => write!(f, "libctru result code: {:08X}", err), + Error::Os(err) => f + .debug_struct("Error") + .field("raw", &format_args!("{:#08X}", err)) + .field("description", &R_DESCRIPTION(err)) + .field("module", &R_MODULE(err)) + .field("summary", &R_SUMMARY(err)) + .field("level", &R_LEVEL(err)) + .finish(), } } } -// TODO: Expand libctru result code into human-readable error message +// TODO: Expand libctru result code into human-readable error message. These should be useful: +// https://www.3dbrew.org/wiki/Error_codes +// https://github.com/devkitPro/libctru/blob/master/libctru/include/3ds/result.h impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/ctru-sys/src/lib.rs b/ctru-sys/src/lib.rs index d91d887..454a380 100644 --- a/ctru-sys/src/lib.rs +++ b/ctru-sys/src/lib.rs @@ -1,9 +1,12 @@ #![no_std] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(clippy::all)] + +pub mod result; -#[allow(non_upper_case_globals)] -#[allow(non_camel_case_types)] -#[allow(non_snake_case)] -#[allow(clippy::all)] mod bindings; pub use bindings::*; +pub use result::*; diff --git a/ctru-sys/src/result.rs b/ctru-sys/src/result.rs new file mode 100644 index 0000000..5f54694 --- /dev/null +++ b/ctru-sys/src/result.rs @@ -0,0 +1,42 @@ +//! Ports of macros in +//! + +use crate::Result; + +/// Checks whether a result code indicates success. +pub fn R_SUCCEEDED(res: Result) -> bool { + res >= 0 +} + +/// Checks whether a result code indicates failure. +pub fn R_FAILED(res: Result) -> bool { + res < 0 +} + +/// Returns the level of a result code. +pub fn R_LEVEL(res: Result) -> Result { + (res >> 27) & 0x1F +} + +/// Returns the summary of a result code. +pub fn R_SUMMARY(res: Result) -> Result { + (res >> 21) & 0x3F +} + +/// Returns the module ID of a result code. +pub fn R_MODULE(res: Result) -> Result { + (res >> 10) & 0xFF +} + +/// Returns the description of a result code. +pub fn R_DESCRIPTION(res: Result) -> Result { + res & 0x3FF +} + +/// Builds a result code from its constituent components. +pub fn MAKERESULT(level: Result, summary: Result, module: Result, description: Result) -> Result { + ((level & 0x1F) << 27) + | ((summary & 0x3F) << 21) + | ((module & 0xFF) << 10) + | (description & 0x3FF) +}