@@ -120,12 +120,28 @@ impl Transaction {
120
120
Transaction :: new ( TransactionKind :: WaitForState ( state) )
121
121
}
122
122
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
+
123
131
/// Crate a new wait_for_edge transaction
124
132
#[ cfg( feature = "embedded-hal-async" ) ]
125
133
pub fn wait_for_edge ( edge : Edge ) -> Transaction {
126
134
Transaction :: new ( TransactionKind :: WaitForEdge ( edge) )
127
135
}
128
136
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
+
129
145
/// Add an error return to a transaction
130
146
///
131
147
/// This is used to mock failure behaviours.
@@ -157,9 +173,15 @@ pub enum TransactionKind {
157
173
/// Wait for the given pin state
158
174
#[ cfg( feature = "embedded-hal-async" ) ]
159
175
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 ) ,
160
179
/// Wait for the given pin edge
161
180
#[ cfg( feature = "embedded-hal-async" ) ]
162
181
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 ) ,
163
185
}
164
186
165
187
impl TransactionKind {
@@ -309,6 +331,9 @@ impl StatefulOutputPin for Mock {
309
331
}
310
332
}
311
333
334
+ #[ cfg( feature = "embedded-hal-async" ) ]
335
+ use futures:: future:: pending;
336
+
312
337
#[ cfg( feature = "embedded-hal-async" ) ]
313
338
impl embedded_hal_async:: digital:: Wait for Mock {
314
339
/// Wait for the pin to go high
@@ -320,14 +345,18 @@ impl embedded_hal_async::digital::Wait for Mock {
320
345
. expect ( "no expectation for pin::wait_for_high call" ) ;
321
346
322
347
assert ! (
323
- matches!( kind, TransactionKind :: WaitForState ( State :: High ) ) ,
348
+ matches!(
349
+ kind,
350
+ TransactionKind :: WaitForState ( State :: High )
351
+ | TransactionKind :: WaitForStateForever ( State :: High )
352
+ ) ,
324
353
"got call to wait_for_high"
325
354
) ;
326
355
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 ,
331
360
}
332
361
}
333
362
@@ -339,14 +368,18 @@ impl embedded_hal_async::digital::Wait for Mock {
339
368
s. next ( ) . expect ( "no expectation for pin::wait_for_low call" ) ;
340
369
341
370
assert ! (
342
- matches!( kind, TransactionKind :: WaitForState ( State :: Low ) ) ,
371
+ matches!(
372
+ kind,
373
+ TransactionKind :: WaitForState ( State :: Low )
374
+ | TransactionKind :: WaitForStateForever ( State :: Low )
375
+ ) ,
343
376
"got call to wait_for_low"
344
377
) ;
345
378
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 ,
350
383
}
351
384
}
352
385
@@ -359,14 +392,18 @@ impl embedded_hal_async::digital::Wait for Mock {
359
392
. expect ( "no expectation for pin::wait_for_rising_edge call" ) ;
360
393
361
394
assert ! (
362
- matches!( kind, TransactionKind :: WaitForEdge ( Edge :: Rising ) ) ,
395
+ matches!(
396
+ kind,
397
+ TransactionKind :: WaitForEdge ( Edge :: Rising )
398
+ | TransactionKind :: WaitForEdgeForever ( Edge :: Rising )
399
+ ) ,
363
400
"got call to wait_for_rising_edge"
364
401
) ;
365
402
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 ,
370
407
}
371
408
}
372
409
@@ -379,14 +416,18 @@ impl embedded_hal_async::digital::Wait for Mock {
379
416
. expect ( "no expectation for pin::wait_for_falling_edge call" ) ;
380
417
381
418
assert ! (
382
- matches!( kind, TransactionKind :: WaitForEdge ( Edge :: Falling ) ) ,
419
+ matches!(
420
+ kind,
421
+ TransactionKind :: WaitForEdge ( Edge :: Falling )
422
+ | TransactionKind :: WaitForEdgeForever ( Edge :: Falling )
423
+ ) ,
383
424
"got call to wait_for_falling_edge"
384
425
) ;
385
426
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 ,
390
431
}
391
432
}
392
433
@@ -399,24 +440,32 @@ impl embedded_hal_async::digital::Wait for Mock {
399
440
. expect ( "no expectation for pin::wait_for_any_edge call" ) ;
400
441
401
442
assert ! (
402
- matches!( kind, TransactionKind :: WaitForEdge ( Edge :: Any ) ) ,
443
+ matches!(
444
+ kind,
445
+ TransactionKind :: WaitForEdge ( Edge :: Any )
446
+ | TransactionKind :: WaitForEdgeForever ( Edge :: Any )
447
+ ) ,
403
448
"got call to wait_for_any_edge"
404
449
) ;
405
450
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 ,
410
455
}
411
456
}
412
457
}
413
458
414
459
#[ cfg( test) ]
415
460
mod test {
416
461
use std:: io:: ErrorKind ;
462
+ #[ cfg( feature = "embedded-hal-async" ) ]
463
+ use std:: time:: Duration ;
417
464
418
465
use eh1 as embedded_hal;
419
466
use embedded_hal:: digital:: { InputPin , OutputPin , StatefulOutputPin } ;
467
+ #[ cfg( feature = "embedded-hal-async" ) ]
468
+ use tokio:: time:: timeout;
420
469
421
470
use super :: {
422
471
super :: error:: MockError ,
@@ -528,6 +577,35 @@ mod test {
528
577
pin. done ( ) ;
529
578
}
530
579
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
+
531
609
#[ tokio:: test]
532
610
#[ cfg( feature = "embedded-hal-async" ) ]
533
611
async fn test_can_wait_for_edge ( ) {
@@ -553,6 +631,39 @@ mod test {
553
631
pin. done ( ) ;
554
632
}
555
633
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
+
556
667
#[ tokio:: test]
557
668
#[ should_panic( expected = "got call to wait_for_rising_edge" ) ]
558
669
#[ cfg( feature = "embedded-hal-async" ) ]
0 commit comments