1
+ use crate :: ifn:: IFn ;
2
+ use crate :: value:: { ToValue , Value } ;
3
+ use std:: rc:: Rc ;
4
+
5
+ use crate :: error_message;
6
+ use crate :: type_tag:: TypeTag ;
7
+
8
+ /// clojure.string/blank? ; returns true if nil, empty or whitespace
9
+ #[ derive( Debug , Clone ) ]
10
+ pub struct BlankFn { }
11
+ impl ToValue for BlankFn {
12
+ fn to_value ( & self ) -> Value {
13
+ Value :: IFn ( Rc :: new ( self . clone ( ) ) )
14
+ }
15
+ }
16
+ impl IFn for BlankFn {
17
+ fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
18
+ if args. len ( ) != 1 {
19
+ return error_message:: wrong_arg_count ( 1 , args. len ( ) ) ;
20
+ } else {
21
+ match args. get ( 0 ) . unwrap ( ) . to_value ( ) {
22
+ Value :: Nil => Value :: Boolean ( true ) ,
23
+ Value :: String ( s) => {
24
+ if s. len ( ) == 0 {
25
+ Value :: Boolean ( true )
26
+ } else {
27
+ return Value :: Boolean ( s. chars ( ) . filter ( |c| !c. is_whitespace ( ) ) . collect :: < Vec < char > > ( ) . len ( ) == 0 )
28
+ }
29
+ }
30
+ Value :: String ( s) => Value :: String ( s. chars ( ) . rev ( ) . collect ( ) ) ,
31
+ _a => error_message:: type_mismatch ( TypeTag :: String , & _a. to_value ( ) )
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ #[ cfg( test) ]
38
+ mod tests {
39
+ mod reverse_tests {
40
+ use crate :: value:: Value ;
41
+ use std:: rc:: Rc ;
42
+ use crate :: clojure_string:: blank_qmark_:: BlankFn ;
43
+ use crate :: ifn:: IFn ;
44
+
45
+ #[ test]
46
+ fn is_non_empty_string_blank ( ) {
47
+ let blank = BlankFn { } ;
48
+ let s = "hello" ;
49
+ let args = vec ! [ Rc :: new( Value :: String ( String :: from( s) ) ) ] ;
50
+ assert_eq ! ( Value :: Boolean ( false ) , blank. invoke( args) ) ;
51
+ }
52
+
53
+ #[ test]
54
+ fn is_empty_string_blank ( ) {
55
+ let blank = BlankFn { } ;
56
+ let s = "" ;
57
+ let args = vec ! [ Rc :: new( Value :: String ( String :: from( s) ) ) ] ;
58
+ assert_eq ! ( Value :: Boolean ( true ) , blank. invoke( args) ) ;
59
+ }
60
+
61
+ #[ test]
62
+ fn is_string_with_whitespace_only_blank ( ) {
63
+ let blank = BlankFn { } ;
64
+ let s = " \t \n \r " ;
65
+ let args = vec ! [ Rc :: new( Value :: String ( String :: from( s) ) ) ] ;
66
+ assert_eq ! ( Value :: Boolean ( true ) , blank. invoke( args) ) ;
67
+ }
68
+
69
+ #[ test]
70
+ fn is_string_with_whitespace_and_text_blank ( ) {
71
+ let blank = BlankFn { } ;
72
+ let s = " \t hello \n \r " ;
73
+ let args = vec ! [ Rc :: new( Value :: String ( String :: from( s) ) ) ] ;
74
+ assert_eq ! ( Value :: Boolean ( true ) , blank. invoke( args) ) ;
75
+ }
76
+
77
+ #[ test]
78
+ fn is_nil_blank ( ) {
79
+ let blank = BlankFn { } ;
80
+ let args = vec ! [ Rc :: new( Value :: Nil ) ] ;
81
+ assert_eq ! ( Value :: Boolean ( true ) , blank. invoke( args) ) ;
82
+ }
83
+ }
84
+ }
0 commit comments