@@ -120,12 +120,28 @@ impl Transaction {
120120 Transaction :: new ( TransactionKind :: WaitForState ( state) )
121121 }
122122
123+ /// Create a new wait_for_state transaction,
124+ /// which returns a forever-Pending future when called.
125+ /// This simulates waiting on a pin that never changes.
126+ #[ cfg( feature = "embedded-hal-async" ) ]
127+ pub fn wait_for_state_forever ( state : State ) -> Transaction {
128+ Transaction :: new ( TransactionKind :: WaitForStateForever ( state) )
129+ }
130+
123131 /// Crate a new wait_for_edge transaction
124132 #[ cfg( feature = "embedded-hal-async" ) ]
125133 pub fn wait_for_edge ( edge : Edge ) -> Transaction {
126134 Transaction :: new ( TransactionKind :: WaitForEdge ( edge) )
127135 }
128136
137+ /// Crate a new wait_for_edge transaction,
138+ /// which returns a forever-Pending future when called.
139+ /// This simulates waiting on a pin that never changes.
140+ #[ cfg( feature = "embedded-hal-async" ) ]
141+ pub fn wait_for_edge_forever ( edge : Edge ) -> Transaction {
142+ Transaction :: new ( TransactionKind :: WaitForEdgeForever ( edge) )
143+ }
144+
129145 /// Add an error return to a transaction
130146 ///
131147 /// This is used to mock failure behaviours.
@@ -157,9 +173,15 @@ pub enum TransactionKind {
157173 /// Wait for the given pin state
158174 #[ cfg( feature = "embedded-hal-async" ) ]
159175 WaitForState ( State ) ,
176+ /// Wait for the given pin state, returning Pending to simulate a never-changing pin
177+ #[ cfg( feature = "embedded-hal-async" ) ]
178+ WaitForStateForever ( State ) ,
160179 /// Wait for the given pin edge
161180 #[ cfg( feature = "embedded-hal-async" ) ]
162181 WaitForEdge ( Edge ) ,
182+ /// Wait for the given pin edge, returning Pending to simulate a never-changing pin
183+ #[ cfg( feature = "embedded-hal-async" ) ]
184+ WaitForEdgeForever ( Edge ) ,
163185}
164186
165187impl TransactionKind {
@@ -309,6 +331,9 @@ impl StatefulOutputPin for Mock {
309331 }
310332}
311333
334+ #[ cfg( feature = "embedded-hal-async" ) ]
335+ use futures:: future:: pending;
336+
312337#[ cfg( feature = "embedded-hal-async" ) ]
313338impl embedded_hal_async:: digital:: Wait for Mock {
314339 /// Wait for the pin to go high
@@ -320,14 +345,18 @@ impl embedded_hal_async::digital::Wait for Mock {
320345 . expect ( "no expectation for pin::wait_for_high call" ) ;
321346
322347 assert ! (
323- matches!( kind, TransactionKind :: WaitForState ( State :: High ) ) ,
348+ matches!(
349+ kind,
350+ TransactionKind :: WaitForState ( State :: High )
351+ | TransactionKind :: WaitForStateForever ( State :: High )
352+ ) ,
324353 "got call to wait_for_high"
325354 ) ;
326355
327- if let Some ( e ) = err {
328- Err ( e)
329- } else {
330- Ok ( ( ) )
356+ match ( kind , err) {
357+ ( _ , Some ( e ) ) => Err ( e) ,
358+ ( TransactionKind :: WaitForState ( State :: High ) , _ ) => Ok ( ( ) ) ,
359+ _ => pending ( ) . await ,
331360 }
332361 }
333362
@@ -339,14 +368,18 @@ impl embedded_hal_async::digital::Wait for Mock {
339368 s. next ( ) . expect ( "no expectation for pin::wait_for_low call" ) ;
340369
341370 assert ! (
342- matches!( kind, TransactionKind :: WaitForState ( State :: Low ) ) ,
371+ matches!(
372+ kind,
373+ TransactionKind :: WaitForState ( State :: Low )
374+ | TransactionKind :: WaitForStateForever ( State :: Low )
375+ ) ,
343376 "got call to wait_for_low"
344377 ) ;
345378
346- if let Some ( e ) = err {
347- Err ( e)
348- } else {
349- Ok ( ( ) )
379+ match ( kind , err) {
380+ ( _ , Some ( e ) ) => Err ( e) ,
381+ ( TransactionKind :: WaitForState ( State :: Low ) , _ ) => Ok ( ( ) ) ,
382+ _ => pending ( ) . await ,
350383 }
351384 }
352385
@@ -359,14 +392,18 @@ impl embedded_hal_async::digital::Wait for Mock {
359392 . expect ( "no expectation for pin::wait_for_rising_edge call" ) ;
360393
361394 assert ! (
362- matches!( kind, TransactionKind :: WaitForEdge ( Edge :: Rising ) ) ,
395+ matches!(
396+ kind,
397+ TransactionKind :: WaitForEdge ( Edge :: Rising )
398+ | TransactionKind :: WaitForEdgeForever ( Edge :: Rising )
399+ ) ,
363400 "got call to wait_for_rising_edge"
364401 ) ;
365402
366- if let Some ( e ) = err {
367- Err ( e)
368- } else {
369- Ok ( ( ) )
403+ match ( kind , err) {
404+ ( _ , Some ( e ) ) => Err ( e) ,
405+ ( TransactionKind :: WaitForEdge ( Edge :: Rising ) , _ ) => Ok ( ( ) ) ,
406+ _ => pending ( ) . await ,
370407 }
371408 }
372409
@@ -379,14 +416,18 @@ impl embedded_hal_async::digital::Wait for Mock {
379416 . expect ( "no expectation for pin::wait_for_falling_edge call" ) ;
380417
381418 assert ! (
382- matches!( kind, TransactionKind :: WaitForEdge ( Edge :: Falling ) ) ,
419+ matches!(
420+ kind,
421+ TransactionKind :: WaitForEdge ( Edge :: Falling )
422+ | TransactionKind :: WaitForEdgeForever ( Edge :: Falling )
423+ ) ,
383424 "got call to wait_for_falling_edge"
384425 ) ;
385426
386- if let Some ( e ) = err {
387- Err ( e)
388- } else {
389- Ok ( ( ) )
427+ match ( kind , err) {
428+ ( _ , Some ( e ) ) => Err ( e) ,
429+ ( TransactionKind :: WaitForEdge ( Edge :: Falling ) , _ ) => Ok ( ( ) ) ,
430+ _ => pending ( ) . await ,
390431 }
391432 }
392433
@@ -399,24 +440,32 @@ impl embedded_hal_async::digital::Wait for Mock {
399440 . expect ( "no expectation for pin::wait_for_any_edge call" ) ;
400441
401442 assert ! (
402- matches!( kind, TransactionKind :: WaitForEdge ( Edge :: Any ) ) ,
443+ matches!(
444+ kind,
445+ TransactionKind :: WaitForEdge ( Edge :: Any )
446+ | TransactionKind :: WaitForEdgeForever ( Edge :: Any )
447+ ) ,
403448 "got call to wait_for_any_edge"
404449 ) ;
405450
406- if let Some ( e ) = err {
407- Err ( e)
408- } else {
409- Ok ( ( ) )
451+ match ( kind , err) {
452+ ( _ , Some ( e ) ) => Err ( e) ,
453+ ( TransactionKind :: WaitForEdge ( Edge :: Any ) , _ ) => Ok ( ( ) ) ,
454+ _ => pending ( ) . await ,
410455 }
411456 }
412457}
413458
414459#[ cfg( test) ]
415460mod test {
416461 use std:: io:: ErrorKind ;
462+ #[ cfg( feature = "embedded-hal-async" ) ]
463+ use std:: time:: Duration ;
417464
418465 use eh1 as embedded_hal;
419466 use embedded_hal:: digital:: { InputPin , OutputPin , StatefulOutputPin } ;
467+ #[ cfg( feature = "embedded-hal-async" ) ]
468+ use tokio:: time:: timeout;
420469
421470 use super :: {
422471 super :: error:: MockError ,
@@ -528,6 +577,35 @@ mod test {
528577 pin. done ( ) ;
529578 }
530579
580+ #[ tokio:: test]
581+ #[ cfg( feature = "embedded-hal-async" ) ]
582+ async fn test_can_wait_for_state_forever ( ) {
583+ use embedded_hal_async:: digital:: Wait ;
584+
585+ let expectations = [
586+ Transaction :: new ( TransactionKind :: WaitForStateForever ( State :: High ) ) ,
587+ Transaction :: new ( TransactionKind :: WaitForStateForever ( State :: Low ) ) ,
588+ Transaction :: new ( TransactionKind :: WaitForStateForever ( State :: High ) )
589+ . with_error ( MockError :: Io ( ErrorKind :: NotConnected ) ) ,
590+ ] ;
591+ let mut pin = Mock :: new ( & expectations) ;
592+
593+ // we should not return Ok while asking to wait forever!
594+ timeout ( Duration :: from_millis ( 10 ) , pin. wait_for_high ( ) )
595+ . await
596+ . expect_err ( "expected wait_for_high timeout" ) ;
597+ timeout ( Duration :: from_millis ( 10 ) , pin. wait_for_low ( ) )
598+ . await
599+ . expect_err ( "expected wait_for_low timeout" ) ;
600+
601+ // errors are still returned, since maybe awaiting on the pin failed for some reason
602+ pin. wait_for_high ( )
603+ . await
604+ . expect_err ( "expected error return" ) ;
605+
606+ pin. done ( ) ;
607+ }
608+
531609 #[ tokio:: test]
532610 #[ cfg( feature = "embedded-hal-async" ) ]
533611 async fn test_can_wait_for_edge ( ) {
@@ -553,6 +631,39 @@ mod test {
553631 pin. done ( ) ;
554632 }
555633
634+ #[ tokio:: test]
635+ #[ cfg( feature = "embedded-hal-async" ) ]
636+ async fn test_can_wait_for_edge_forever ( ) {
637+ use embedded_hal_async:: digital:: Wait ;
638+
639+ let expectations = [
640+ Transaction :: new ( TransactionKind :: WaitForEdgeForever ( Edge :: Rising ) ) ,
641+ Transaction :: new ( TransactionKind :: WaitForEdgeForever ( Edge :: Falling ) ) ,
642+ Transaction :: new ( TransactionKind :: WaitForEdgeForever ( Edge :: Any ) ) ,
643+ Transaction :: new ( TransactionKind :: WaitForEdgeForever ( Edge :: Rising ) )
644+ . with_error ( MockError :: Io ( ErrorKind :: NotConnected ) ) ,
645+ ] ;
646+ let mut pin = Mock :: new ( & expectations) ;
647+
648+ // we should not return Ok while asking to wait forever!
649+ timeout ( Duration :: from_millis ( 10 ) , pin. wait_for_rising_edge ( ) )
650+ . await
651+ . expect_err ( "expected wait_for_rising_edge timeout" ) ;
652+ timeout ( Duration :: from_millis ( 10 ) , pin. wait_for_falling_edge ( ) )
653+ . await
654+ . expect_err ( "expected wait_for_falling_edge timeout" ) ;
655+ timeout ( Duration :: from_millis ( 10 ) , pin. wait_for_any_edge ( ) )
656+ . await
657+ . expect_err ( "expected wait_for_any_edge timeout" ) ;
658+
659+ // errors are still returned, since maybe awaiting on the pin failed for some reason
660+ pin. wait_for_rising_edge ( )
661+ . await
662+ . expect_err ( "expected error return" ) ;
663+
664+ pin. done ( ) ;
665+ }
666+
556667 #[ tokio:: test]
557668 #[ should_panic( expected = "got call to wait_for_rising_edge" ) ]
558669 #[ cfg( feature = "embedded-hal-async" ) ]
0 commit comments