1
- use cirru_edn:: { Edn , EdnListView } ;
1
+ use std:: sync:: Arc ;
2
+
3
+ use cirru_edn:: { Edn , EdnAnyRef , EdnListView } ;
2
4
use regex:: Regex ;
3
5
4
6
#[ no_mangle]
5
7
pub fn abi_version ( ) -> String {
6
- String :: from ( "0.0.7" )
8
+ String :: from ( "0.0.8" )
9
+ }
10
+
11
+ #[ no_mangle]
12
+ pub fn re_pattern ( args : Vec < Edn > ) -> Result < Edn , String > {
13
+ if args. len ( ) == 1 {
14
+ match & args[ 0 ] {
15
+ Edn :: Str ( s) => match Regex :: new ( s) {
16
+ Ok ( pattern) => Ok ( Edn :: AnyRef ( EdnAnyRef ( Arc :: from ( pattern) ) ) ) ,
17
+ Err ( e) => Err ( format ! ( "re-pattern failed, {}" , e) ) ,
18
+ } ,
19
+ _ => Err ( format ! ( "re-pattern expect 1 string, got {:?}" , args) ) ,
20
+ }
21
+ } else {
22
+ Err ( format ! ( "re-pattern expect 1 string, got {:?}" , args) )
23
+ }
7
24
}
8
25
9
26
#[ no_mangle]
@@ -14,6 +31,13 @@ pub fn re_matches(args: Vec<Edn>) -> Result<Edn, String> {
14
31
Ok ( p) => Ok ( Edn :: Bool ( p. is_match ( s) ) ) ,
15
32
Err ( e) => Err ( format ! ( "re-matches failed, {}" , e) ) ,
16
33
} ,
34
+ ( Edn :: Str ( s) , Edn :: AnyRef ( EdnAnyRef ( p) ) ) => {
35
+ if let Some ( pattern) = p. downcast_ref :: < Regex > ( ) {
36
+ Ok ( Edn :: Bool ( pattern. is_match ( s) ) )
37
+ } else {
38
+ Err ( format ! ( "re-matches expected a regex, got {:?}" , p) )
39
+ }
40
+ }
17
41
( _, _) => Err ( format ! ( "re-matches expected 2 strings: {:?}" , args) ) ,
18
42
}
19
43
} else {
@@ -34,6 +58,16 @@ pub fn re_find_index(args: Vec<Edn>) -> Result<Edn, String> {
34
58
Err ( e) => Err ( format ! ( "re-find-index failed, {}" , e) ) ,
35
59
}
36
60
}
61
+ ( Edn :: Str ( s) , Edn :: AnyRef ( EdnAnyRef ( p) ) ) => {
62
+ if let Some ( pattern) = p. downcast_ref :: < Regex > ( ) {
63
+ match pattern. find ( s) {
64
+ Some ( matched) => Ok ( Edn :: Number ( matched. start ( ) as f64 ) ) ,
65
+ None => Ok ( Edn :: Number ( -1.0 ) ) , // TODO maybe nil
66
+ }
67
+ } else {
68
+ Err ( format ! ( "re-find-index expected a regex, got {:?}" , p) )
69
+ }
70
+ }
37
71
( _, _) => Err ( format ! ( "re-find-index expected 2 strings: {:?}" , args) ) ,
38
72
}
39
73
} else {
@@ -51,13 +85,24 @@ pub fn re_find(args: Vec<Edn>) -> Result<Edn, String> {
51
85
Ok ( p) => {
52
86
let mut matched = p. find_iter ( s) ;
53
87
match matched. next ( ) {
54
- Some ( v) => Ok ( Edn :: Str ( v. as_str ( ) . to_string ( ) . into ( ) ) ) ,
55
- None => Ok ( Edn :: Str ( "" . to_owned ( ) . into ( ) ) ) , // TODO maybe nil
88
+ Some ( v) => Ok ( Edn :: str ( v. as_str ( ) . to_string ( ) ) ) ,
89
+ None => Ok ( Edn :: from ( "" ) ) , // TODO maybe nil
56
90
}
57
91
}
58
92
Err ( e) => Err ( format ! ( "re-find failed, {}" , e) ) ,
59
93
}
60
94
}
95
+ ( Edn :: Str ( s) , Edn :: AnyRef ( EdnAnyRef ( p) ) ) => {
96
+ if let Some ( pattern) = p. downcast_ref :: < Regex > ( ) {
97
+ let mut matched = pattern. find_iter ( s) ;
98
+ match matched. next ( ) {
99
+ Some ( v) => Ok ( Edn :: str ( v. as_str ( ) . to_string ( ) ) ) ,
100
+ None => Ok ( Edn :: from ( "" ) ) , // TODO maybe nil
101
+ }
102
+ } else {
103
+ Err ( format ! ( "re-find expected a regex, got {:?}" , p) )
104
+ }
105
+ }
61
106
( _, _) => Err ( format ! ( "re-find expected 2 strings: {:?}" , args) ) ,
62
107
}
63
108
} else {
@@ -79,6 +124,17 @@ pub fn re_find_all(args: Vec<Edn>) -> Result<Edn, String> {
79
124
}
80
125
Err ( e) => Err ( format ! ( "re-find-all failed, {}" , e) ) ,
81
126
} ,
127
+ ( Edn :: Str ( s) , Edn :: AnyRef ( EdnAnyRef ( p) ) ) => {
128
+ if let Some ( pattern) = p. downcast_ref :: < Regex > ( ) {
129
+ let mut ys: Vec < Edn > = vec ! [ ] ;
130
+ for v in pattern. find_iter ( s) {
131
+ ys. push ( Edn :: Str ( v. as_str ( ) . to_string ( ) . into ( ) ) )
132
+ }
133
+ Ok ( Edn :: List ( EdnListView ( ys) ) )
134
+ } else {
135
+ Err ( format ! ( "re-find-all expected a regex, got {:?}" , p) )
136
+ }
137
+ }
82
138
( _, _) => Err ( format ! ( "re-find-all expected 2 strings: {:?}" , args) ) ,
83
139
}
84
140
} else {
@@ -100,6 +156,17 @@ pub fn re_split(args: Vec<Edn>) -> Result<Edn, String> {
100
156
}
101
157
Err ( e) => Err ( format ! ( "re-split failed, {}" , e) ) ,
102
158
} ,
159
+ ( Edn :: Str ( s) , Edn :: AnyRef ( EdnAnyRef ( p) ) ) => {
160
+ if let Some ( pattern) = p. downcast_ref :: < Regex > ( ) {
161
+ let mut ys: Vec < Edn > = vec ! [ ] ;
162
+ for piece in pattern. split ( s) {
163
+ ys. push ( Edn :: str ( piece) ) ;
164
+ }
165
+ Ok ( Edn :: List ( EdnListView ( ys) ) )
166
+ } else {
167
+ Err ( format ! ( "re-split expected a regex, got {:?}" , p) )
168
+ }
169
+ }
103
170
( _, _) => Err ( format ! ( "re-split expected 2 strings: {:?}" , args) ) ,
104
171
}
105
172
} else {
@@ -115,6 +182,13 @@ pub fn re_replace_all(args: Vec<Edn>) -> Result<Edn, String> {
115
182
Ok ( p) => Ok ( Edn :: str ( p. replace_all ( s, & * * next) . into_owned ( ) ) ) ,
116
183
Err ( e) => Err ( format ! ( "re-replace-all failed, {}" , e) ) ,
117
184
} ,
185
+ ( Edn :: Str ( s) , Edn :: AnyRef ( EdnAnyRef ( p) ) , Edn :: Str ( next) ) => {
186
+ if let Some ( pattern) = p. downcast_ref :: < Regex > ( ) {
187
+ Ok ( Edn :: str ( pattern. replace_all ( s, & * * next) . into_owned ( ) ) )
188
+ } else {
189
+ Err ( format ! ( "re-replace-all expected a regex, got {:?}" , p) )
190
+ }
191
+ }
118
192
( a, b, c) => Err ( format ! ( "re-replace-all expected 3 strings: {} {} {}" , a, b, c) ) ,
119
193
}
120
194
} else {
0 commit comments