@@ -21,6 +21,21 @@ pub enum Key {
2121 Esc ,
2222}
2323
24+ #[ cfg( any( feature = "crossterm" , feature = "termion" ) ) ]
25+ enum Action < T > {
26+ Continue ,
27+ Result ( Result < T , std:: io:: Error > ) ,
28+ }
29+
30+ #[ cfg( any( feature = "crossterm" , feature = "termion" ) ) ]
31+ fn continue_on_interrupt < T > ( result : Result < T , std:: io:: Error > ) -> Action < T > {
32+ match result {
33+ Ok ( v) => Action :: Result ( Ok ( v) ) ,
34+ Err ( err) if err. kind ( ) == std:: io:: ErrorKind :: Interrupted => Action :: Continue ,
35+ Err ( err) => Action :: Result ( Err ( err) ) ,
36+ }
37+ }
38+
2439mod convert {
2540 #[ cfg( any( feature = "crossterm" , feature = "termion" ) ) ]
2641 use super :: Key ;
@@ -94,14 +109,21 @@ mod convert {
94109
95110#[ cfg( feature = "crossterm" ) ]
96111mod _impl {
112+ use crate :: input:: { continue_on_interrupt, Action } ;
113+
97114 /// Return a receiver of user input events to avoid blocking the main thread.
98115 pub fn key_input_channel ( ) -> std:: sync:: mpsc:: Receiver < super :: Key > {
99116 use std:: convert:: TryInto ;
100117
101118 let ( key_send, key_receive) = std:: sync:: mpsc:: sync_channel ( 0 ) ;
102119 std:: thread:: spawn ( move || -> Result < ( ) , std:: io:: Error > {
103120 loop {
104- let event = crossterm:: event:: read ( ) . map_err ( crate :: crossterm_utils:: into_io_error) ?;
121+ let event = match continue_on_interrupt (
122+ crossterm:: event:: read ( ) . map_err ( crate :: crossterm_utils:: into_io_error) ,
123+ ) {
124+ Action :: Continue => continue ,
125+ Action :: Result ( res) => res?,
126+ } ;
105127 match event {
106128 crossterm:: event:: Event :: Key ( key) => {
107129 let key: Result < super :: Key , _ > = key. try_into ( ) ;
@@ -137,6 +159,8 @@ mod _impl {
137159
138160#[ cfg( all( feature = "termion" , not( feature = "crossterm" ) ) ) ]
139161mod _impl {
162+ use crate :: input:: { continue_on_interrupt, Action } ;
163+
140164 /// Return a stream of user input events.
141165 ///
142166 /// Requires feature `futures-channel`
@@ -149,7 +173,10 @@ mod _impl {
149173 // This brings blocking key-handling into the async world
150174 std:: thread:: spawn ( move || -> Result < ( ) , io:: Error > {
151175 for key in io:: stdin ( ) . keys ( ) {
152- let key: Result < super :: Key , _ > = key?. try_into ( ) ;
176+ let key: Result < super :: Key , _ > = match continue_on_interrupt ( key) {
177+ Action :: Continue => continue ,
178+ Action :: Result ( res) => res?. try_into ( ) ,
179+ } ;
153180 if let Ok ( key) = key {
154181 if futures_lite:: future:: block_on ( key_send. send ( key) ) . is_err ( ) {
155182 break ;
@@ -168,7 +195,10 @@ mod _impl {
168195 let ( key_send, key_receive) = std:: sync:: mpsc:: sync_channel ( 0 ) ;
169196 std:: thread:: spawn ( move || -> Result < ( ) , io:: Error > {
170197 for key in io:: stdin ( ) . keys ( ) {
171- let key: Result < super :: Key , _ > = key?. try_into ( ) ;
198+ let key: Result < super :: Key , _ > = match continue_on_interrupt ( key) {
199+ Action :: Continue => continue ,
200+ Action :: Result ( res) => res?. try_into ( ) ,
201+ } ;
172202 if let Ok ( key) = key {
173203 if key_send. send ( key) . is_err ( ) {
174204 break ;
0 commit comments