1
- use std:: { cmp:: Ordering , fmt:: Debug , io, iter, str:: FromStr } ;
1
+ use std:: {
2
+ cmp:: Ordering ,
3
+ fmt:: Debug ,
4
+ io, iter,
5
+ str:: FromStr ,
6
+ sync:: { Arc , Mutex } ,
7
+ } ;
2
8
3
9
use console:: { Key , Term } ;
4
10
@@ -8,11 +14,11 @@ use crate::completion::Completion;
8
14
use crate :: history:: History ;
9
15
use crate :: {
10
16
theme:: { render:: TermThemeRenderer , SimpleTheme , Theme } ,
11
- validate:: Validator ,
17
+ validate:: InputValidator ,
12
18
Result ,
13
19
} ;
14
20
15
- type ValidatorCallback < ' a , T > = Box < dyn FnMut ( & T ) -> Option < String > + ' a > ;
21
+ type InputValidatorCallback < ' a , T > = Arc < Mutex < dyn FnMut ( & T ) -> Option < String > + ' a > > ;
16
22
17
23
/// Renders an input prompt.
18
24
///
@@ -45,6 +51,7 @@ type ValidatorCallback<'a, T> = Box<dyn FnMut(&T) -> Option<String> + 'a>;
45
51
/// println!("Your name is: {}", name);
46
52
/// }
47
53
/// ```
54
+ #[ derive( Clone ) ]
48
55
pub struct Input < ' a , T > {
49
56
prompt : String ,
50
57
post_completion_text : Option < String > ,
@@ -54,9 +61,9 @@ pub struct Input<'a, T> {
54
61
initial_text : Option < String > ,
55
62
theme : & ' a dyn Theme ,
56
63
permit_empty : bool ,
57
- validator : Option < ValidatorCallback < ' a , T > > ,
64
+ validator : Option < InputValidatorCallback < ' a , T > > ,
58
65
#[ cfg( feature = "history" ) ]
59
- history : Option < & ' a mut dyn History < T > > ,
66
+ history : Option < Arc < Mutex < & ' a mut dyn History < T > > > > ,
60
67
#[ cfg( feature = "completion" ) ]
61
68
completion : Option < & ' a dyn Completion > ,
62
69
}
@@ -207,7 +214,7 @@ impl<'a, T> Input<'a, T> {
207
214
where
208
215
H : History < T > ,
209
216
{
210
- self . history = Some ( history) ;
217
+ self . history = Some ( Arc :: new ( Mutex :: new ( history) ) ) ;
211
218
self
212
219
}
213
220
@@ -249,14 +256,14 @@ where
249
256
/// ```
250
257
pub fn validate_with < V > ( mut self , mut validator : V ) -> Self
251
258
where
252
- V : Validator < T > + ' a ,
259
+ V : InputValidator < T > + ' a ,
253
260
V :: Err : ToString ,
254
261
{
255
262
let mut old_validator_func = self . validator . take ( ) ;
256
263
257
- self . validator = Some ( Box :: new ( move |value : & T | -> Option < String > {
264
+ self . validator = Some ( Arc :: new ( Mutex :: new ( move |value : & T | -> Option < String > {
258
265
if let Some ( old) = old_validator_func. as_mut ( ) {
259
- if let Some ( err) = old ( value) {
266
+ if let Some ( err) = old. lock ( ) . unwrap ( ) ( value) {
260
267
return Some ( err) ;
261
268
}
262
269
}
@@ -265,7 +272,7 @@ where
265
272
Ok ( ( ) ) => None ,
266
273
Err ( err) => Some ( err. to_string ( ) ) ,
267
274
}
268
- } ) ) ;
275
+ } ) ) ) ;
269
276
270
277
self
271
278
}
@@ -491,7 +498,7 @@ where
491
498
Key :: ArrowUp => {
492
499
let line_size = term. size ( ) . 1 as usize ;
493
500
if let Some ( history) = & self . history {
494
- if let Some ( previous) = history. read ( hist_pos) {
501
+ if let Some ( previous) = history. lock ( ) . unwrap ( ) . read ( hist_pos) {
495
502
hist_pos += 1 ;
496
503
let mut chars_len = chars. len ( ) ;
497
504
while ( ( prompt_len + chars_len) / line_size) > 0 {
@@ -550,7 +557,7 @@ where
550
557
hist_pos = pos;
551
558
// Move it back again to get the previous history entry
552
559
if let Some ( pos) = pos. checked_sub ( 1 ) {
553
- if let Some ( previous) = history. read ( pos) {
560
+ if let Some ( previous) = history. lock ( ) . unwrap ( ) . read ( pos) {
554
561
for ch in previous. chars ( ) {
555
562
chars. insert ( position, ch) ;
556
563
position += 1 ;
@@ -574,7 +581,7 @@ where
574
581
if chars. is_empty ( ) {
575
582
if let Some ( ref default) = self . default {
576
583
if let Some ( ref mut validator) = self . validator {
577
- if let Some ( err) = validator ( default) {
584
+ if let Some ( err) = validator. lock ( ) . unwrap ( ) ( default) {
578
585
render. error ( & err) ?;
579
586
continue ;
580
587
}
@@ -594,11 +601,11 @@ where
594
601
Ok ( value) => {
595
602
#[ cfg( feature = "history" ) ]
596
603
if let Some ( history) = & mut self . history {
597
- history. write ( & value) ;
604
+ history. lock ( ) . unwrap ( ) . write ( & value) ;
598
605
}
599
606
600
607
if let Some ( ref mut validator) = self . validator {
601
- if let Some ( err) = validator ( & value) {
608
+ if let Some ( err) = validator. lock ( ) . unwrap ( ) ( & value) {
602
609
render. error ( & err) ?;
603
610
continue ;
604
611
}
@@ -675,7 +682,7 @@ where
675
682
if input. is_empty ( ) {
676
683
if let Some ( ref default) = self . default {
677
684
if let Some ( ref mut validator) = self . validator {
678
- if let Some ( err) = validator ( default) {
685
+ if let Some ( err) = validator. lock ( ) . unwrap ( ) ( default) {
679
686
render. error ( & err) ?;
680
687
continue ;
681
688
}
@@ -694,7 +701,7 @@ where
694
701
match input. parse :: < T > ( ) {
695
702
Ok ( value) => {
696
703
if let Some ( ref mut validator) = self . validator {
697
- if let Some ( err) = validator ( & value) {
704
+ if let Some ( err) = validator. lock ( ) . unwrap ( ) ( & value) {
698
705
render. error ( & err) ?;
699
706
continue ;
700
707
}
@@ -715,3 +722,15 @@ where
715
722
}
716
723
}
717
724
}
725
+
726
+ #[ cfg( test) ]
727
+ mod tests {
728
+ use super :: * ;
729
+
730
+ #[ test]
731
+ fn test_clone ( ) {
732
+ let input = Input :: < String > :: new ( ) . with_prompt ( "Your name" ) ;
733
+
734
+ let _ = input. clone ( ) ;
735
+ }
736
+ }
0 commit comments