Fix returning error if the device state is invalid and leads to invalid date/time values

pull/8/head
Diego Barrios Romero 2021-05-22 23:09:10 +02:00
parent 0b17437d4c
commit 9c6fe164b8
4 changed files with 44 additions and 15 deletions

View File

@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased] ## [Unreleased]
... ### Changed
- [breaking-change] Return `Error::InvalidDeviceState` if it was not possible to read the
date and/or time from the device because the state of the device corresponds to
an invalid date and/or time.
## [0.3.2] - 2021-02-22 ## [0.3.2] - 2021-02-22

View File

@ -1,6 +1,8 @@
//! Common implementation //! Common implementation
use super::{decimal_to_packed_bcd, hours_to_register, packed_bcd_to_decimal}; use super::{
decimal_to_packed_bcd, hours_to_register, packed_bcd_to_decimal, some_or_invalid_error,
};
use crate::{ use crate::{
interface::{ReadData, WriteData}, interface::{ReadData, WriteData},
BitFlags, Datelike, Ds323x, Error, Hours, NaiveDate, NaiveDateTime, NaiveTime, Register, Rtcc, BitFlags, Datelike, Ds323x, Error, Hours, NaiveDate, NaiveDateTime, NaiveTime, Register, Rtcc,
@ -33,11 +35,8 @@ where
let minute = packed_bcd_to_decimal(data[Register::MINUTES as usize + 1]); let minute = packed_bcd_to_decimal(data[Register::MINUTES as usize + 1]);
let second = packed_bcd_to_decimal(data[Register::SECONDS as usize + 1]); let second = packed_bcd_to_decimal(data[Register::SECONDS as usize + 1]);
Ok(NaiveTime::from_hms( let time = NaiveTime::from_hms_opt(get_h24(hour).into(), minute.into(), second.into());
get_h24(hour).into(), some_or_invalid_error(time)
minute.into(),
second.into(),
))
} }
fn get_weekday(&mut self) -> Result<u8, Self::Error> { fn get_weekday(&mut self) -> Result<u8, Self::Error> {
@ -74,7 +73,8 @@ where
let month = let month =
packed_bcd_to_decimal(data[Register::MONTH as usize + 1 - offset] & !BitFlags::CENTURY); packed_bcd_to_decimal(data[Register::MONTH as usize + 1 - offset] & !BitFlags::CENTURY);
let day = packed_bcd_to_decimal(data[Register::DOM as usize + 1 - offset]); let day = packed_bcd_to_decimal(data[Register::DOM as usize + 1 - offset]);
Ok(NaiveDate::from_ymd(year.into(), month.into(), day.into())) let date = NaiveDate::from_ymd_opt(year.into(), month.into(), day.into());
some_or_invalid_error(date)
} }
fn get_datetime(&mut self) -> Result<NaiveDateTime, Self::Error> { fn get_datetime(&mut self) -> Result<NaiveDateTime, Self::Error> {
@ -91,13 +91,10 @@ where
let minute = packed_bcd_to_decimal(data[Register::MINUTES as usize + 1]); let minute = packed_bcd_to_decimal(data[Register::MINUTES as usize + 1]);
let second = packed_bcd_to_decimal(data[Register::SECONDS as usize + 1]); let second = packed_bcd_to_decimal(data[Register::SECONDS as usize + 1]);
Ok( let date = NaiveDate::from_ymd_opt(year.into(), month.into(), day.into());
rtcc::NaiveDate::from_ymd(year.into(), month.into(), day.into()).and_hms( let date = some_or_invalid_error(date)?;
get_h24(hour).into(), let datetime = date.and_hms_opt(get_h24(hour).into(), minute.into(), second.into());
minute.into(), some_or_invalid_error(datetime)
second.into(),
),
)
} }
fn set_seconds(&mut self, seconds: u8) -> Result<(), Self::Error> { fn set_seconds(&mut self, seconds: u8) -> Result<(), Self::Error> {

View File

@ -28,10 +28,34 @@ fn hours_to_register<CommE, PinE>(hours: Hours) -> Result<u8, Error<CommE, PinE>
} }
} }
fn some_or_invalid_error<T, CommE, PinE>(data: Option<T>) -> Result<T, Error<CommE, PinE>> {
if let Some(data) = data {
Ok(data)
} else {
Err(Error::InvalidDeviceState)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn if_some_then_get_inner() {
match some_or_invalid_error::<u8, (), ()>(Some(1)) {
Ok(1) => (),
_ => panic!(),
}
}
#[test]
fn if_none_then_error() {
match some_or_invalid_error::<u8, (), ()>(None) {
Err(Error::InvalidDeviceState) => (),
_ => panic!(),
}
}
#[test] #[test]
fn can_convert_packed_bcd_to_decimal() { fn can_convert_packed_bcd_to_decimal() {
assert_eq!(0, packed_bcd_to_decimal(0b0000_0000)); assert_eq!(0, packed_bcd_to_decimal(0b0000_0000));

View File

@ -408,6 +408,11 @@ pub enum Error<CommE, PinE> {
Pin(PinE), Pin(PinE),
/// Invalid input data provided /// Invalid input data provided
InvalidInputData, InvalidInputData,
/// Internal device state is invalid.
///
/// It was not possible to read a valid date and/or time.
/// The device is probably missing initialization.
InvalidDeviceState,
} }
/// Square-wave output frequency /// Square-wave output frequency