diff --git a/Cargo.toml b/Cargo.toml index 30eb95e..15bd369 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,10 +22,11 @@ embedded-hal = { package = "embedded-hal", version = "^1.0" } embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] } serde = { version = "1", features = ["derive"], default-features = false, optional = true } embedded-hal-async = { package = "embedded-hal-async", version = "^1.0", optional = true } +linux-embedded-hal = "0.3.2" [dev-dependencies] i2cdev = "0.5.1" -linux-embedded-hal = "0.3.0" + [package.metadata.docs.rs] all-features = true diff --git a/examples/basic.rs b/examples/basic.rs index 19a162c..d0454e1 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,11 +1,10 @@ //! This example reads the chip ID from a RV8803. - -use i2cdev::linux::LinuxI2CError; use linux_embedded_hal::I2cdev; -use rv8803::models::{Rv8803, Rv8803Error, TIME_ARRAY_LENGTH}; +use rv8803::models::{CrateError, Rv8803, TIME_ARRAY_LENGTH}; -fn main() -> Result<(), Rv8803Error> { - let i2c = I2cdev::new("/dev/i2c-1").map_err(Rv8803Error::I2c)?; +fn main() -> Result<(), CrateError> { + let dev = I2cdev::new("/dev/i2c-1"); + let i2c = dev.map_err(CrateError::default())?; let mut rtc: Rv8803<_> = Rv8803::from_i2c(i2c, rv8803::bus::Address::Default).expect("Failed to initialize RV8803"); diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..d28c8e1 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2024-02-22" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index e64e9c6..7f28cf9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,10 @@ #![cfg_attr(docsrs, feature(doc_cfg), feature(doc_auto_cfg))] #![forbid(unsafe_code)] #![warn(missing_docs)] +#![feature(error_in_core)] +#![feature(error_generic_member_access)] +#![feature(fn_traits)] +#![feature(unboxed_closures)] use crate::bus::{Bus, BusTrait}; pub use embedded_hal_0_2; diff --git a/src/models.rs b/src/models.rs index 0611c82..061a02f 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,9 +1,69 @@ /// All possible errors in this crate +use alloc::boxed::Box; +use core::{error, fmt::Display}; + +/// Type for all crate errors +pub type CrateError = Error; +/// Boxed error type +pub type BoxError = Box; + #[allow(dead_code)] #[derive(Debug)] -pub enum Rv8803Error { - /// I2C bus error - I2c(E), +/// Error struct +pub struct Error { + inner: BoxError, +} + +impl Error { + /// Create a new instance of [`Error`] + pub fn new(error: impl Into) -> Self { + Self { + inner: error.into(), + } + } + + /// Create a default instance of [`Error`] + #[allow(clippy::should_implement_trait)] + #[allow(clippy::unnecessary_literal_unwrap)] + pub fn default() -> Self { + Self { + // FIXME: isn't this the same as `panic!("{:?}", ())`?? + inner: Err(()).unwrap(), + } + } +} + +impl FnOnce<(linux_embedded_hal::i2cdev::linux::LinuxI2CError,)> for Error { + type Output = Error; + + extern "rust-call" fn call_once( + self, + args: (linux_embedded_hal::i2cdev::linux::LinuxI2CError,), + ) -> Self::Output { + Error::new(args.0) + } +} + +impl Display for CrateError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.inner.fmt(f) + } +} + +impl error::Error for CrateError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(&*self.inner) + } + + fn description(&self) -> &str { + "description() is deprecated; use Display" + } + + fn cause(&self) -> Option<&dyn error::Error> { + self.source() + } + + fn provide<'a>(&'a self, _request: &mut core::error::Request<'a>) {} } /// Mapping of all the registers used to operate the RTC module