Better detect incorrect input for alarms, refactor some test macros

Alarm can be triggered on a subset of input, no need to reject ignored
fields (eg. don't care about day field when matching on time only). We still
need to set these to correct values as they are still used to set alarm
registers.

Test macro have been refactored to accept variable number of arguments.
pull/5/head
Marc Poulhiès 2020-06-17 16:05:34 +02:00 committed by Diego Barrios Romero
parent 8c5bb16030
commit 092af13298
2 changed files with 507 additions and 114 deletions

View File

@ -5,6 +5,12 @@ use super::{decimal_to_packed_bcd, hours_to_register};
use interface::{ReadData, WriteData}; use interface::{ReadData, WriteData};
/// Parameters for setting Alarm1 on a day of the month /// Parameters for setting Alarm1 on a day of the month
///
/// Depending on the matching strategy, some fields may not be relevant. In this
/// case, invalid values are ignored and basic values are used instead to
/// configure the alarm:
/// - second, minute and hour : 0
/// - day: 1
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct DayAlarm1 { pub struct DayAlarm1 {
/// Day of the month [1-31] /// Day of the month [1-31]
@ -18,6 +24,12 @@ pub struct DayAlarm1 {
} }
/// Parameters for setting Alarm1 on a weekday /// Parameters for setting Alarm1 on a weekday
///
/// Depending on the matching strategy, some fields may not be relevant. In this
/// case, invalid values are ignored and basic values are used instead to
/// configure the alarm:
/// - second, minute and hour : 0
/// - weekday: 1
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct WeekdayAlarm1 { pub struct WeekdayAlarm1 {
/// Weekday [1-7] /// Weekday [1-7]
@ -46,6 +58,12 @@ pub enum Alarm1Matching {
} }
/// Parameters for setting Alarm2 on a day of the month /// Parameters for setting Alarm2 on a day of the month
///
/// Depending on the matching strategy, some fields may not be relevant. In this
/// case, invalid values are ignored and basic values are used instead to
/// configure the alarm:
/// - minute and hour : 0
/// - day: 1
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct DayAlarm2 { pub struct DayAlarm2 {
/// Day of month [1-31] /// Day of month [1-31]
@ -57,6 +75,12 @@ pub struct DayAlarm2 {
} }
/// Parameters for setting Alarm2 on a weekday /// Parameters for setting Alarm2 on a weekday
///
/// Depending on the matching strategy, some fields may not be relevant. In this
/// case, invalid values are ignored and basic values are used instead to
/// configure the alarm:
/// - minute and hour : 0
/// - weekday: 1
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct WeekdayAlarm2 { pub struct WeekdayAlarm2 {
/// Weekday [1-7] /// Weekday [1-7]
@ -101,92 +125,187 @@ fn get_matching_mask_alarm2(matching: Alarm2Matching) -> [u8; 3] {
} }
} }
/// Test if hours value is valid
///
/// Will return true if valid, false if not
fn is_hour_valid(hours: Hours) -> bool {
match hours {
Hours::H24(h) if h > 23 => true,
Hours::AM(h) if h < 1 || h > 12 => true,
Hours::PM(h) if h < 1 || h > 12 => true,
_ => false,
}
}
/// Relax the hour value by changing an incorrect value by 0
fn relax_hour(hours: Hours) -> Hours {
match hours {
Hours::H24(h) if h > 23 => Hours::H24(0),
Hours::H24(h) => Hours::H24(h),
Hours::AM(h) if h < 1 || h > 12 => Hours::AM(1),
Hours::AM(h) => Hours::AM(h),
Hours::PM(h) if h < 1 || h > 12 => Hours::PM(1),
Hours::PM(h) => Hours::PM(h),
}
}
impl<DI, IC, CommE, PinE> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>, DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
{ {
/// Set Alarm1 for day of the month. /// Set Alarm1 for day of the month.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the used parameters
/// (depending on the matching startegy) is out of range. Any unused
/// parameter is set to basic valid value:
/// - second, minute, hour: 0
/// - day: 1
pub fn set_alarm1_day( pub fn set_alarm1_day(
&mut self, &mut self,
when: DayAlarm1, when: DayAlarm1,
matching: Alarm1Matching, matching: Alarm1Matching,
) -> Result<(), Error<CommE, PinE>> { ) -> Result<(), Error<CommE, PinE>> {
if when.day < 1 || when.day > 31 || when.minute > 59 || when.second > 59 { let day_invalid = when.day < 1 || when.day > 31;
let hour_invalid = is_hour_valid(when.hour);
let minute_invalid = when.minute > 59;
let second_invalid = when.second > 59;
let day = if day_invalid { 1 } else { when.day };
let hour = relax_hour(when.hour);
let minute = if minute_invalid { 0 } else { when.minute };
if (matching == Alarm1Matching::AllMatch && (day_invalid || hour_invalid))
|| (hour_invalid && matching == Alarm1Matching::HoursMinutesAndSecondsMatch)
|| ((matching != Alarm1Matching::SecondsMatch
&& matching != Alarm1Matching::OncePerSecond)
&& minute_invalid)
|| second_invalid
{
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let match_mask = get_matching_mask_alarm1(matching); let match_mask = get_matching_mask_alarm1(matching);
let mut data = [ let mut data = [
Register::ALARM1_SECONDS, Register::ALARM1_SECONDS,
decimal_to_packed_bcd(when.second) | match_mask[0], decimal_to_packed_bcd(when.second) | match_mask[0],
decimal_to_packed_bcd(when.minute) | match_mask[1], decimal_to_packed_bcd(minute) | match_mask[1],
hours_to_register(when.hour)? | match_mask[2], hours_to_register(hour)? | match_mask[2],
decimal_to_packed_bcd(when.day) | match_mask[3], decimal_to_packed_bcd(day) | match_mask[3],
]; ];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }
/// Set Alarm1 for weekday. /// Set Alarm1 for weekday.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the used parameters
/// (depending on the matching startegy) is out of range. Any unused
/// parameter is set to basic valid value:
/// - second, minute, hour: 0
/// - weekday: 1
pub fn set_alarm1_weekday( pub fn set_alarm1_weekday(
&mut self, &mut self,
when: WeekdayAlarm1, when: WeekdayAlarm1,
matching: Alarm1Matching, matching: Alarm1Matching,
) -> Result<(), Error<CommE, PinE>> { ) -> Result<(), Error<CommE, PinE>> {
if when.weekday < 1 || when.weekday > 7 || when.minute > 59 || when.second > 59 { let weekday_invalid = when.weekday < 1 || when.weekday > 7;
let hour_invalid = is_hour_valid(when.hour);
let minute_invalid = when.minute > 59;
let second_invalid = when.second > 59;
let weekday = if weekday_invalid { 1 } else { when.weekday };
let hour = relax_hour(when.hour);
let minute = if minute_invalid { 0 } else { when.minute };
let second = if second_invalid { 0 } else { when.second };
if ((hour_invalid || weekday_invalid) && matching == Alarm1Matching::AllMatch)
|| (hour_invalid && matching == Alarm1Matching::HoursMinutesAndSecondsMatch)
|| (minute_invalid
&& (matching != Alarm1Matching::OncePerSecond
&& matching != Alarm1Matching::SecondsMatch))
|| (second_invalid && matching != Alarm1Matching::OncePerSecond)
{
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let match_mask = get_matching_mask_alarm1(matching); let match_mask = get_matching_mask_alarm1(matching);
let mut data = [ let mut data = [
Register::ALARM1_SECONDS, Register::ALARM1_SECONDS,
decimal_to_packed_bcd(when.second) | match_mask[0], decimal_to_packed_bcd(second) | match_mask[0],
decimal_to_packed_bcd(when.minute) | match_mask[1], decimal_to_packed_bcd(minute) | match_mask[1],
hours_to_register(when.hour)? | match_mask[2], hours_to_register(hour)? | match_mask[2],
decimal_to_packed_bcd(when.weekday) | match_mask[3] | BitFlags::WEEKDAY, decimal_to_packed_bcd(weekday) | match_mask[3] | BitFlags::WEEKDAY,
]; ];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }
/// Set Alarm2 for date (day of month). /// Set Alarm2 for date (day of month).
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the used parameters
/// (depending on the matching startegy) is out of range. Any unused
/// parameter is set to basic valid value:
/// - minute, hour: 0
/// - day: 1
pub fn set_alarm2_day( pub fn set_alarm2_day(
&mut self, &mut self,
when: DayAlarm2, when: DayAlarm2,
matching: Alarm2Matching, matching: Alarm2Matching,
) -> Result<(), Error<CommE, PinE>> { ) -> Result<(), Error<CommE, PinE>> {
if when.day < 1 || when.day > 31 || when.minute > 59 { let day_invalid = when.day < 1 || when.day > 31;
let hour_invalid = is_hour_valid(when.hour);
let minute_invalid = when.minute > 59;
let day = if day_invalid { 1 } else { when.day };
let hour = relax_hour(when.hour);
let minute = if minute_invalid { 0 } else { when.minute };
if ((day_invalid || hour_invalid) && matching == Alarm2Matching::AllMatch)
|| (hour_invalid && matching == Alarm2Matching::HoursAndMinutesMatch)
|| (matching != Alarm2Matching::OncePerMinute && minute_invalid)
{
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let match_mask = get_matching_mask_alarm2(matching); let match_mask = get_matching_mask_alarm2(matching);
let mut data = [ let mut data = [
Register::ALARM2_MINUTES, Register::ALARM2_MINUTES,
decimal_to_packed_bcd(when.minute) | match_mask[0], decimal_to_packed_bcd(minute) | match_mask[0],
hours_to_register(when.hour)? | match_mask[1], hours_to_register(hour)? | match_mask[1],
decimal_to_packed_bcd(when.day) | match_mask[2], decimal_to_packed_bcd(day) | match_mask[2],
]; ];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }
/// Set Alarm2 for weekday. /// Set Alarm2 for weekday.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the used parameters
/// (depending on the matching startegy) is out of range. Any unused
/// parameter is set to basic valid value:
/// - minute, hour: 0
/// - weekday: 1
pub fn set_alarm2_weekday( pub fn set_alarm2_weekday(
&mut self, &mut self,
when: WeekdayAlarm2, when: WeekdayAlarm2,
matching: Alarm2Matching, matching: Alarm2Matching,
) -> Result<(), Error<CommE, PinE>> { ) -> Result<(), Error<CommE, PinE>> {
if when.weekday < 1 || when.weekday > 7 || when.minute > 59 { let weekday_invalid = when.weekday < 1 || when.weekday > 7;
let hour_invalid = is_hour_valid(when.hour);
let minute_invalid = when.minute > 59;
let weekday = if weekday_invalid { 1 } else { when.weekday };
let hour = relax_hour(when.hour);
let minute = if minute_invalid { 0 } else { when.minute };
if (matching == Alarm2Matching::AllMatch && (weekday_invalid || hour_invalid))
|| (matching == Alarm2Matching::HoursAndMinutesMatch && hour_invalid)
|| (minute_invalid && matching != Alarm2Matching::OncePerMinute)
{
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let match_mask = get_matching_mask_alarm2(matching); let match_mask = get_matching_mask_alarm2(matching);
let mut data = [ let mut data = [
Register::ALARM2_MINUTES, Register::ALARM2_MINUTES,
decimal_to_packed_bcd(when.minute) | match_mask[0], decimal_to_packed_bcd(minute) | match_mask[0],
hours_to_register(when.hour)? | match_mask[1], hours_to_register(hour)? | match_mask[1],
decimal_to_packed_bcd(when.weekday) | match_mask[2] | BitFlags::WEEKDAY, decimal_to_packed_bcd(weekday) | match_mask[2] | BitFlags::WEEKDAY,
]; ];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }

View File

@ -14,18 +14,18 @@ use ds323x::{
#[macro_export] #[macro_export]
macro_rules! _set_invalid_alarm_test { macro_rules! _set_invalid_alarm_test {
($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $alarm:expr, $matching:expr) => { ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $( $value:expr ),+) => {
#[test] #[test]
fn $name() { fn $name() {
let mut dev = $create_method(&[]); let mut dev = $create_method(&[]);
assert_invalid_input_data!(dev.$method($alarm, $matching)); assert_invalid_input_data!(dev.$method($($value),*));
$destroy_method(dev); $destroy_method(dev);
} }
}; };
} }
macro_rules! set_invalid_alarm_test { macro_rules! set_invalid_alarm_test {
($name:ident, $method:ident, $alarm:expr, $matching:expr) => { ($name:ident, $method:ident, $( $value:expr ),+) => {
mod $name { mod $name {
use super::*; use super::*;
_set_invalid_alarm_test!( _set_invalid_alarm_test!(
@ -33,24 +33,21 @@ macro_rules! set_invalid_alarm_test {
$method, $method,
new_ds3231, new_ds3231,
destroy_ds3231, destroy_ds3231,
$alarm, $($value),*
$matching
); );
_set_invalid_alarm_test!( _set_invalid_alarm_test!(
cannot_set_invalid_ds3232, cannot_set_invalid_ds3232,
$method, $method,
new_ds3232, new_ds3232,
destroy_ds3232, destroy_ds3232,
$alarm, $($value),*
$matching
); );
_set_invalid_alarm_test!( _set_invalid_alarm_test!(
cannot_set_invalid_ds3234, cannot_set_invalid_ds3234,
$method, $method,
new_ds3234, new_ds3234,
destroy_ds3234, destroy_ds3234,
$alarm, $($value),*
$matching
); );
} }
}; };
@ -80,6 +77,28 @@ mod alarm1 {
}, },
A1M::AllMatch A1M::AllMatch
); );
set_invalid_alarm_test!(
day_invalid_second,
set_alarm1_day,
DayAlarm1 {
day: 1,
hour: Hours::H24(1),
minute: 59,
second: 60
},
A1M::SecondsMatch
);
set_invalid_alarm_test!(
day_invalid_minute,
set_alarm1_day,
DayAlarm1 {
day: 1,
hour: Hours::H24(1),
minute: 60,
second: 10
},
A1M::MinutesAndSecondsMatch
);
set_invalid_alarm_test!( set_invalid_alarm_test!(
day_invalid_h, day_invalid_h,
set_alarm1_day, set_alarm1_day,
@ -91,6 +110,17 @@ mod alarm1 {
}, },
A1M::AllMatch A1M::AllMatch
); );
set_invalid_alarm_test!(
day_invalid_h_hmasm,
set_alarm1_day,
DayAlarm1 {
day: 1,
hour: Hours::H24(24),
minute: 1,
second: 1
},
A1M::HoursMinutesAndSecondsMatch
);
set_invalid_alarm_test!( set_invalid_alarm_test!(
day_invalid_am1, day_invalid_am1,
set_alarm1_day, set_alarm1_day,
@ -191,6 +221,18 @@ mod alarm1 {
}, },
A1M::AllMatch A1M::AllMatch
); );
set_invalid_alarm_test!(
wd_invalid_h_hmasm,
set_alarm1_weekday,
WeekdayAlarm1 {
weekday: 1,
hour: Hours::H24(24),
minute: 1,
second: 1
},
A1M::HoursMinutesAndSecondsMatch
);
set_invalid_alarm_test!( set_invalid_alarm_test!(
wd_invalid_am1, wd_invalid_am1,
set_alarm1_weekday, set_alarm1_weekday,
@ -257,10 +299,42 @@ mod alarm1 {
}, },
A1M::AllMatch A1M::AllMatch
); );
set_invalid_alarm_test!(
wd_invalid_sec_sm,
set_alarm1_weekday,
WeekdayAlarm1 {
weekday: 1,
hour: Hours::H24(1),
minute: 1,
second: 60
},
A1M::SecondsMatch
);
set_invalid_alarm_test!(
wd_invalid_min_masm,
set_alarm1_weekday,
WeekdayAlarm1 {
weekday: 1,
hour: Hours::H24(1),
minute: 60,
second: 1
},
A1M::MinutesAndSecondsMatch
);
} }
mod alarm2 { mod alarm2 {
use super::*; use super::*;
set_invalid_alarm_test!(
day_invalid_min_mm,
set_alarm2_day,
DayAlarm2 {
day: 1,
hour: Hours::H24(1),
minute: 60
},
A2M::MinutesMatch
);
set_invalid_alarm_test!( set_invalid_alarm_test!(
day_invalid_min, day_invalid_min,
set_alarm2_day, set_alarm2_day,
@ -281,6 +355,16 @@ mod alarm2 {
}, },
A2M::AllMatch A2M::AllMatch
); );
set_invalid_alarm_test!(
day_invalid_h_hamm,
set_alarm2_day,
DayAlarm2 {
day: 1,
hour: Hours::H24(24),
minute: 1
},
A2M::HoursAndMinutesMatch
);
set_invalid_alarm_test!( set_invalid_alarm_test!(
day_invalid_am1, day_invalid_am1,
set_alarm2_day, set_alarm2_day,
@ -342,6 +426,16 @@ mod alarm2 {
A2M::AllMatch A2M::AllMatch
); );
set_invalid_alarm_test!(
wd_invalid_min_mm,
set_alarm2_weekday,
WeekdayAlarm2 {
weekday: 1,
hour: Hours::H24(1),
minute: 60
},
A2M::MinutesMatch
);
set_invalid_alarm_test!( set_invalid_alarm_test!(
wd_invalid_min, wd_invalid_min,
set_alarm2_weekday, set_alarm2_weekday,
@ -362,6 +456,16 @@ mod alarm2 {
}, },
A2M::AllMatch A2M::AllMatch
); );
set_invalid_alarm_test!(
wd_invalid_h_hmm,
set_alarm2_weekday,
WeekdayAlarm2 {
weekday: 1,
hour: Hours::H24(24),
minute: 1
},
A2M::HoursAndMinutesMatch
);
set_invalid_alarm_test!( set_invalid_alarm_test!(
wd_invalid_am1, wd_invalid_am1,
set_alarm2_weekday, set_alarm2_weekday,
@ -422,22 +526,32 @@ mod alarm2 {
}, },
A2M::AllMatch A2M::AllMatch
); );
set_invalid_alarm_test!(
wd_invalid_minute,
set_alarm2_weekday,
WeekdayAlarm2 {
weekday: 1,
hour: Hours::H24(1),
minute: 60
},
A2M::HoursAndMinutesMatch
);
} }
macro_rules! _set_values_test { macro_rules! _set_values_test {
($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $value1:expr, $value2:expr, $transactions:expr) => { ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $transactions:expr, $( $value:expr ),+) => {
#[test] #[test]
fn $name() { fn $name() {
let trans = $transactions; let trans = $transactions;
let mut dev = $create_method(&trans); let mut dev = $create_method(&trans);
dev.$method($value1, $value2).unwrap(); dev.$method($($value),*).unwrap();
$destroy_method(dev); $destroy_method(dev);
} }
}; };
} }
macro_rules! set_values_test { macro_rules! set_values_test {
($name:ident, $method:ident, $value1:expr, $value2:expr, $i2c_transactions:expr, $spi_transactions:expr) => { ($name:ident, $method:ident, $i2c_transactions:expr, $spi_transactions:expr, $( $value:expr ),+) => {
mod $name { mod $name {
use super::*; use super::*;
_set_values_test!( _set_values_test!(
@ -445,37 +559,36 @@ macro_rules! set_values_test {
$method, $method,
new_ds3231, new_ds3231,
destroy_ds3231, destroy_ds3231,
$value1, $i2c_transactions,
$value2, $($value),*
$i2c_transactions
); );
_set_values_test!( _set_values_test!(
can_set_ds3232, can_set_ds3232,
$method, $method,
new_ds3232, new_ds3232,
destroy_ds3232, destroy_ds3232,
$value1, $i2c_transactions,
$value2, $($value),*
$i2c_transactions
); );
_set_values_test!( _set_values_test!(
can_set_ds3234, can_set_ds3234,
$method, $method,
new_ds3234, new_ds3234,
destroy_ds3234, destroy_ds3234,
$value1, $spi_transactions,
$value2, $($value),*
$spi_transactions
); );
} }
}; };
} }
macro_rules! set_alarm_test { macro_rules! set_alarm_test {
($name:ident, $method:ident, $alarm:expr, $matching:expr, $register:ident, [ $( $registers:expr ),+ ]) => { ($name:ident, $method:ident, $register:ident, [ $( $registers:expr ),+ ], $( $value:expr ),+) => {
set_values_test!($name, $method, $alarm, $matching, set_values_test!($name, $method,
[ I2cTrans::write(DEV_ADDR, vec![Register::$register, $( $registers ),*]) ], [ I2cTrans::write(DEV_ADDR, vec![Register::$register, $( $registers ),*]) ],
[ SpiTrans::write(vec![Register::$register + 0x80, $( $registers ),*]) ]); [ SpiTrans::write(vec![Register::$register + 0x80, $( $registers ),*]) ],
$($value),*
);
}; };
} }
@ -486,94 +599,146 @@ mod alarm1_day {
set_alarm_test!( set_alarm_test!(
h24, h24,
set_alarm1_day, set_alarm1_day,
ALARM1_SECONDS,
[4, 3, 2, 1],
DayAlarm1 { DayAlarm1 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::AllMatch, A1M::AllMatch
ALARM1_SECONDS,
[4, 3, 2, 1]
); );
set_alarm_test!( set_alarm_test!(
am, am,
set_alarm1_day, set_alarm1_day,
ALARM1_SECONDS,
[4, 3, 0b0100_0010, 1],
DayAlarm1 { DayAlarm1 {
day: 1, day: 1,
hour: Hours::AM(2), hour: Hours::AM(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::AllMatch, A1M::AllMatch
ALARM1_SECONDS,
[4, 3, 0b0100_0010, 1]
); );
set_alarm_test!( set_alarm_test!(
pm, pm,
set_alarm1_day, set_alarm1_day,
ALARM1_SECONDS,
[4, 3, 0b0110_0010, 1],
DayAlarm1 { DayAlarm1 {
day: 1, day: 1,
hour: Hours::PM(2), hour: Hours::PM(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::AllMatch, A1M::AllMatch
ALARM1_SECONDS,
[4, 3, 0b0110_0010, 1]
); );
set_alarm_test!( set_alarm_test!(
match_hms, match_hms,
set_alarm1_day, set_alarm1_day,
ALARM1_SECONDS,
[4, 3, 2, AM | 1],
DayAlarm1 { DayAlarm1 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::HoursMinutesAndSecondsMatch, A1M::HoursMinutesAndSecondsMatch
);
set_alarm_test!(
match_hms_ignore_incorrect_day,
set_alarm1_day,
ALARM1_SECONDS, ALARM1_SECONDS,
[4, 3, 2, AM | 1] [4, 3, 2, AM | 1],
DayAlarm1 {
day: 0,
hour: Hours::H24(2),
minute: 3,
second: 4
},
A1M::HoursMinutesAndSecondsMatch
);
set_alarm_test!(
match_ms_ignore_invalid_hour,
set_alarm1_day,
ALARM1_SECONDS,
[4, 3, AM | 0, AM | 1],
DayAlarm1 {
day: 1,
hour: Hours::H24(24),
minute: 3,
second: 4
},
A1M::MinutesAndSecondsMatch
); );
set_alarm_test!( set_alarm_test!(
match_ms, match_ms,
set_alarm1_day, set_alarm1_day,
ALARM1_SECONDS,
[4, 3, AM | 2, AM | 1],
DayAlarm1 { DayAlarm1 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::MinutesAndSecondsMatch, A1M::MinutesAndSecondsMatch
);
set_alarm_test!(
match_ms_ignore_incorrect_day,
set_alarm1_day,
ALARM1_SECONDS, ALARM1_SECONDS,
[4, 3, AM | 2, AM | 1] [4, 3, AM | 2, AM | 1],
DayAlarm1 {
day: 0,
hour: Hours::H24(2),
minute: 3,
second: 4
},
A1M::MinutesAndSecondsMatch
); );
set_alarm_test!( set_alarm_test!(
match_s, match_s,
set_alarm1_day, set_alarm1_day,
ALARM1_SECONDS,
[4, AM | 3, AM | 2, AM | 1],
DayAlarm1 { DayAlarm1 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::SecondsMatch, A1M::SecondsMatch
);
set_alarm_test!(
match_s_ignore_incorrect_min,
set_alarm1_day,
ALARM1_SECONDS, ALARM1_SECONDS,
[4, AM | 3, AM | 2, AM | 1] [4, AM | 0, AM | 2, AM | 1],
DayAlarm1 {
day: 1,
hour: Hours::H24(2),
minute: 60,
second: 4
},
A1M::SecondsMatch
); );
set_alarm_test!( set_alarm_test!(
match_ops, match_ops,
set_alarm1_day, set_alarm1_day,
ALARM1_SECONDS,
[AM | 4, AM | 3, AM | 2, AM | 1],
DayAlarm1 { DayAlarm1 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::OncePerSecond, A1M::OncePerSecond
ALARM1_SECONDS,
[AM | 4, AM | 3, AM | 2, AM | 1]
); );
} }
@ -582,94 +747,132 @@ mod alarm1_weekday {
set_alarm_test!( set_alarm_test!(
h24, h24,
set_alarm1_weekday, set_alarm1_weekday,
ALARM1_SECONDS,
[4, 3, 2, BF::WEEKDAY | 1],
WeekdayAlarm1 { WeekdayAlarm1 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::AllMatch, A1M::AllMatch
ALARM1_SECONDS,
[4, 3, 2, BF::WEEKDAY | 1]
); );
set_alarm_test!( set_alarm_test!(
am, am,
set_alarm1_weekday, set_alarm1_weekday,
ALARM1_SECONDS,
[4, 3, 0b0100_0010, BF::WEEKDAY | 1],
WeekdayAlarm1 { WeekdayAlarm1 {
weekday: 1, weekday: 1,
hour: Hours::AM(2), hour: Hours::AM(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::AllMatch, A1M::AllMatch
ALARM1_SECONDS,
[4, 3, 0b0100_0010, BF::WEEKDAY | 1]
); );
set_alarm_test!( set_alarm_test!(
pm, pm,
set_alarm1_weekday, set_alarm1_weekday,
ALARM1_SECONDS,
[4, 3, 0b0110_0010, BF::WEEKDAY | 1],
WeekdayAlarm1 { WeekdayAlarm1 {
weekday: 1, weekday: 1,
hour: Hours::PM(2), hour: Hours::PM(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::AllMatch, A1M::AllMatch
ALARM1_SECONDS, );
[4, 3, 0b0110_0010, BF::WEEKDAY | 1] set_alarm_test!(
match_hms_ignore_incorrect_wd,
set_alarm1_weekday,
ALARM1_SECONDS,
[4, 3, 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm1 {
weekday: 0,
hour: Hours::H24(2),
minute: 3,
second: 4
},
A1M::HoursMinutesAndSecondsMatch
); );
set_alarm_test!( set_alarm_test!(
match_hms, match_hms,
set_alarm1_weekday, set_alarm1_weekday,
ALARM1_SECONDS,
[4, 3, 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm1 { WeekdayAlarm1 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::HoursMinutesAndSecondsMatch, A1M::HoursMinutesAndSecondsMatch
ALARM1_SECONDS,
[4, 3, 2, AM | BF::WEEKDAY | 1]
); );
set_alarm_test!( set_alarm_test!(
match_ms, match_ms,
set_alarm1_weekday, set_alarm1_weekday,
ALARM1_SECONDS,
[4, 3, AM | 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm1 { WeekdayAlarm1 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::MinutesAndSecondsMatch, A1M::MinutesAndSecondsMatch
ALARM1_SECONDS,
[4, 3, AM | 2, AM | BF::WEEKDAY | 1]
); );
set_alarm_test!( set_alarm_test!(
match_s, match_s,
set_alarm1_weekday, set_alarm1_weekday,
ALARM1_SECONDS,
[4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm1 { WeekdayAlarm1 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::SecondsMatch, A1M::SecondsMatch
);
set_alarm_test!(
match_s_ignore_incorrect_min,
set_alarm1_weekday,
ALARM1_SECONDS, ALARM1_SECONDS,
[4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1] [4, AM | 0, AM | 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm1 {
weekday: 1,
hour: Hours::H24(2),
minute: 60,
second: 4
},
A1M::SecondsMatch
); );
set_alarm_test!( set_alarm_test!(
match_ops, match_ops,
set_alarm1_weekday, set_alarm1_weekday,
ALARM1_SECONDS,
[AM | 4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm1 { WeekdayAlarm1 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3, minute: 3,
second: 4 second: 4
}, },
A1M::OncePerSecond, A1M::OncePerSecond
);
set_alarm_test!(
match_ops_ignore_incorrect_sec,
set_alarm1_weekday,
ALARM1_SECONDS, ALARM1_SECONDS,
[AM | 4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1] [AM | 0, AM | 3, AM | 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm1 {
weekday: 1,
hour: Hours::H24(2),
minute: 3,
second: 60
},
A1M::OncePerSecond
); );
} }
@ -678,75 +881,111 @@ mod alarm2_day {
set_alarm_test!( set_alarm_test!(
h24, h24,
set_alarm2_day, set_alarm2_day,
ALARM2_MINUTES,
[3, 2, 1],
DayAlarm2 { DayAlarm2 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3 minute: 3
}, },
A2M::AllMatch, A2M::AllMatch
ALARM2_MINUTES,
[3, 2, 1]
); );
set_alarm_test!( set_alarm_test!(
am, am,
set_alarm2_day, set_alarm2_day,
ALARM2_MINUTES,
[3, 0b0100_0010, 1],
DayAlarm2 { DayAlarm2 {
day: 1, day: 1,
hour: Hours::AM(2), hour: Hours::AM(2),
minute: 3 minute: 3
}, },
A2M::AllMatch, A2M::AllMatch
ALARM2_MINUTES,
[3, 0b0100_0010, 1]
); );
set_alarm_test!( set_alarm_test!(
pm, pm,
set_alarm2_day, set_alarm2_day,
ALARM2_MINUTES,
[3, 0b0110_0010, 1],
DayAlarm2 { DayAlarm2 {
day: 1, day: 1,
hour: Hours::PM(2), hour: Hours::PM(2),
minute: 3 minute: 3
}, },
A2M::AllMatch, A2M::AllMatch
ALARM2_MINUTES,
[3, 0b0110_0010, 1]
); );
set_alarm_test!( set_alarm_test!(
match_hm, match_hm,
set_alarm2_day, set_alarm2_day,
ALARM2_MINUTES,
[3, 2, AM | 1],
DayAlarm2 { DayAlarm2 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3 minute: 3
}, },
A2M::HoursAndMinutesMatch, A2M::HoursAndMinutesMatch
);
set_alarm_test!(
match_hm_ignore_incorrect_day,
set_alarm2_day,
ALARM2_MINUTES, ALARM2_MINUTES,
[3, 2, AM | 1] [3, 2, AM | 1],
DayAlarm2 {
day: 0,
hour: Hours::H24(2),
minute: 3
},
A2M::HoursAndMinutesMatch
); );
set_alarm_test!( set_alarm_test!(
match_m, match_m,
set_alarm2_day, set_alarm2_day,
ALARM2_MINUTES,
[3, AM | 2, AM | 1],
DayAlarm2 { DayAlarm2 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3 minute: 3
}, },
A2M::MinutesMatch, A2M::MinutesMatch
);
set_alarm_test!(
match_m_ignore_invalid_h,
set_alarm2_day,
ALARM2_MINUTES, ALARM2_MINUTES,
[3, AM | 2, AM | 1] [3, AM | 0, AM | 1],
DayAlarm2 {
day: 1,
hour: Hours::H24(25),
minute: 3
},
A2M::MinutesMatch
); );
set_alarm_test!( set_alarm_test!(
match_opm, match_opm,
set_alarm2_day, set_alarm2_day,
ALARM2_MINUTES,
[AM | 3, AM | 2, AM | 1],
DayAlarm2 { DayAlarm2 {
day: 1, day: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3 minute: 3
}, },
A2M::OncePerMinute, A2M::OncePerMinute
);
set_alarm_test!(
match_opm_ignore_incorrect_min,
set_alarm2_day,
ALARM2_MINUTES, ALARM2_MINUTES,
[AM | 3, AM | 2, AM | 1] [AM | 0, AM | 2, AM | 1],
DayAlarm2 {
day: 1,
hour: Hours::H24(2),
minute: 60
},
A2M::OncePerMinute
); );
} }
@ -755,74 +994,109 @@ mod alarm2_weekday {
set_alarm_test!( set_alarm_test!(
h24, h24,
set_alarm2_weekday, set_alarm2_weekday,
ALARM2_MINUTES,
[3, 2, BF::WEEKDAY | 1],
WeekdayAlarm2 { WeekdayAlarm2 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3 minute: 3
}, },
A2M::AllMatch, A2M::AllMatch
ALARM2_MINUTES,
[3, 2, BF::WEEKDAY | 1]
); );
set_alarm_test!( set_alarm_test!(
am, am,
set_alarm2_weekday, set_alarm2_weekday,
ALARM2_MINUTES,
[3, 0b0100_0010, BF::WEEKDAY | 1],
WeekdayAlarm2 { WeekdayAlarm2 {
weekday: 1, weekday: 1,
hour: Hours::AM(2), hour: Hours::AM(2),
minute: 3 minute: 3
}, },
A2M::AllMatch, A2M::AllMatch
ALARM2_MINUTES,
[3, 0b0100_0010, BF::WEEKDAY | 1]
); );
set_alarm_test!( set_alarm_test!(
pm, pm,
set_alarm2_weekday, set_alarm2_weekday,
ALARM2_MINUTES,
[3, 0b0110_0010, BF::WEEKDAY | 1],
WeekdayAlarm2 { WeekdayAlarm2 {
weekday: 1, weekday: 1,
hour: Hours::PM(2), hour: Hours::PM(2),
minute: 3 minute: 3
}, },
A2M::AllMatch, A2M::AllMatch
ALARM2_MINUTES,
[3, 0b0110_0010, BF::WEEKDAY | 1]
); );
set_alarm_test!( set_alarm_test!(
match_hm, match_hm,
set_alarm2_weekday, set_alarm2_weekday,
ALARM2_MINUTES,
[3, 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm2 { WeekdayAlarm2 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3 minute: 3
}, },
A2M::HoursAndMinutesMatch, A2M::HoursAndMinutesMatch
);
set_alarm_test!(
match_hm_ignore_incorrect_wd,
set_alarm2_weekday,
ALARM2_MINUTES, ALARM2_MINUTES,
[3, 2, AM | BF::WEEKDAY | 1] [3, 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm2 {
weekday: 0,
hour: Hours::H24(2),
minute: 3
},
A2M::HoursAndMinutesMatch
); );
set_alarm_test!( set_alarm_test!(
match_m, match_m,
set_alarm2_weekday, set_alarm2_weekday,
ALARM2_MINUTES,
[3, AM | 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm2 { WeekdayAlarm2 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3 minute: 3
}, },
A2M::MinutesMatch, A2M::MinutesMatch
);
set_alarm_test!(
match_m_ignore_invalid_hour,
set_alarm2_weekday,
ALARM2_MINUTES, ALARM2_MINUTES,
[3, AM | 2, AM | BF::WEEKDAY | 1] [3, AM | 0, AM | BF::WEEKDAY | 1],
WeekdayAlarm2 {
weekday: 1,
hour: Hours::H24(24),
minute: 3
},
A2M::MinutesMatch
); );
set_alarm_test!( set_alarm_test!(
match_opm, match_opm,
set_alarm2_weekday, set_alarm2_weekday,
ALARM2_MINUTES,
[AM | 3, AM | 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm2 { WeekdayAlarm2 {
weekday: 1, weekday: 1,
hour: Hours::H24(2), hour: Hours::H24(2),
minute: 3 minute: 3
}, },
A2M::OncePerMinute, A2M::OncePerMinute
);
set_alarm_test!(
match_opm_ignore_incorrect_min,
set_alarm2_weekday,
ALARM2_MINUTES, ALARM2_MINUTES,
[AM | 3, AM | 2, AM | BF::WEEKDAY | 1] [AM | 0, AM | 2, AM | BF::WEEKDAY | 1],
WeekdayAlarm2 {
weekday: 1,
hour: Hours::H24(2),
minute: 60
},
A2M::OncePerMinute
); );
} }