1
1
2
2
use axum:: {
3
- body:: Body ,
4
- extract:: { DefaultBodyLimit , Query } ,
5
- response:: { IntoResponse , Redirect , Response } ,
6
- routing:: get,
7
- Json , Router ,
3
+ body:: Body , extract:: { DefaultBodyLimit , Query } , response:: { IntoResponse , Response } , routing:: { get, post} , Json , Router
8
4
} ;
5
+ use axum_extra:: extract:: Form ;
9
6
10
7
use rustc_version_runtime:: version;
11
8
use serde:: { Deserialize , Serialize } ;
12
9
use tower_http:: { limit:: RequestBodyLimitLayer , services:: ServeFile } ;
10
+ use html_escape:: encode_text;
13
11
14
12
#[ tokio:: main]
15
13
async fn main ( ) {
16
14
// build our application with a single route
17
15
let app = Router :: new ( )
18
- //.route_service("/", get(|| async { Redirect::temporary("https://www.regexplanet.com/advanced/rust/index.html") }))
16
+ //.route_service("/", get(|| async { axum:: Redirect::temporary("https://www.regexplanet.com/advanced/rust/index.html") }))
19
17
. route_service ( "/" , get ( root_handler) )
18
+ . route_service ( "/test.json" , post ( test_handler) )
20
19
. route_service ( "/favicon.ico" , ServeFile :: new ( "static/favicon.ico" ) )
21
20
. route_service ( "/favicon.svg" , ServeFile :: new ( "static/favicon.svg" ) )
22
21
. route_service ( "/robots.txt" , ServeFile :: new ( "static/robots.txt" ) )
23
22
. route_service ( "/status.json" , get ( get_status) )
24
23
. layer ( DefaultBodyLimit :: disable ( ) )
25
24
. layer ( RequestBodyLimitLayer :: new ( 10 * 1024 * 1024 /* 10mb */ ) ) ;
26
25
27
- // run our app with hyper, listening globally on port 3000
28
-
29
26
// get address from environment variable
30
27
let address = std:: env:: var ( "ADDRESS" ) . unwrap_or_else ( |_| "0.0.0.0" . to_string ( ) ) ;
31
28
@@ -89,4 +86,121 @@ async fn root_handler() -> Response<Body> {
89
86
. header ( "Content-Type" , "text/plain; charset=utf-8" )
90
87
. body ( Body :: from ( "Dev server running!" ) )
91
88
. unwrap ( ) ;
89
+ }
90
+
91
+ #[ derive( Deserialize , Serialize , Debug ) ]
92
+ struct TestInput {
93
+ regex : String ,
94
+ #[ serde( default ) ]
95
+ replacement : String ,
96
+ #[ serde( default ) ]
97
+ callback : String ,
98
+ #[ serde( default ) ]
99
+ options : Vec < String > ,
100
+ #[ serde( default ) ]
101
+ #[ serde( rename( deserialize = "input" ) ) ]
102
+ inputs : Vec < String > ,
103
+ }
104
+
105
+ #[ derive( Serialize ) ]
106
+ struct TestOutput {
107
+ success : bool ,
108
+ message : String ,
109
+ html : String ,
110
+ }
111
+
112
+ async fn test_handler ( Form ( test_input) : Form < TestInput > ) -> Response < Body > {
113
+
114
+ let mut html = String :: new ( ) ;
115
+
116
+ html. push_str ( "<table class=\" table table-bordered table-striped\" style=\" width: auto;\" >\n " ) ;
117
+ html. push_str ( "\t <tbody>\n " ) ;
118
+ html. push_str ( "\t \t <tr>\n " ) ;
119
+ html. push_str ( "\t \t \t <td>Regular Expression</td>\n " ) ;
120
+ html. push_str ( & format ! ( "\t \t \t <td><code>{}</code></td>\n " , encode_text( & test_input. regex) ) ) ;
121
+ html. push_str ( "\t \t </tr>\n " ) ;
122
+
123
+ if test_input. replacement != "" {
124
+ html. push_str ( "\t \t <tr>\n " ) ;
125
+ html. push_str ( "\t \t \t <td>Replacement</td>\n " ) ;
126
+ html. push_str ( & format ! ( "\t \t \t <td><code>{}</code></td>\n " , encode_text( & test_input. replacement) ) ) ;
127
+ html. push_str ( "\t \t </tr>\n " ) ;
128
+ }
129
+
130
+ html. push_str ( "\t </tbody>\n " ) ;
131
+ html. push_str ( "</table>" ) ;
132
+
133
+ let the_regex = regex:: RegexBuilder :: new ( & test_input. regex )
134
+ . case_insensitive ( test_input. options . contains ( & "i" . to_string ( ) ) )
135
+ . multi_line ( test_input. options . contains ( & "m" . to_string ( ) ) )
136
+ . dot_matches_new_line ( test_input. options . contains ( & "s" . to_string ( ) ) )
137
+ . build ( ) ;
138
+
139
+ if the_regex. is_err ( ) {
140
+ let err_msg = the_regex. unwrap_err ( ) . to_string ( ) ;
141
+
142
+ html. push_str ( "<div class=\" alert alert-danger\" role=\" alert\" >\n " ) ;
143
+ html. push_str ( & format ! ( "<strong>Error:</strong> {}<br>\n " , encode_text( & err_msg) ) ) ;
144
+ html. push_str ( "</div>\n " ) ;
145
+
146
+ return handle_jsonp ( & test_input. callback , html) ;
147
+ }
148
+
149
+ if test_input. inputs . len ( ) == 0 {
150
+ html. push_str ( "<div class=\" alert alert-danger\" role=\" alert\" >\n " ) ;
151
+ html. push_str ( "No inputs to test!\n " ) ;
152
+ html. push_str ( "</div>\n " ) ;
153
+
154
+ return handle_jsonp ( & test_input. callback , html) ;
155
+ }
156
+
157
+ let the_regex = the_regex. unwrap ( ) ;
158
+
159
+ html. push_str ( "<table class=\" table table-bordered table-striped\" style=\" width: auto;\" >\n " ) ;
160
+ html. push_str ( "\t <thead>\n " ) ;
161
+ html. push_str ( "\t \t <tr>\n " ) ;
162
+ html. push_str ( "\t \t \t <th>Input</th>\n " ) ;
163
+ html. push_str ( "\t \t \t <th>is_match</th>\n " ) ;
164
+ html. push_str ( "\t \t </tr>\n " ) ;
165
+ html. push_str ( "\t </thead>\n " ) ;
166
+ html. push_str ( "\t <tbody>\n " ) ;
167
+
168
+ for input in test_input. inputs {
169
+ //let output = the_regex.as_ref().unwrap().replace_all(&input, &test_input.replacement);
170
+ html. push_str ( "\t \t <tr>\n " ) ;
171
+ html. push_str ( & format ! ( "\t \t \t <td>{}</td>\n " , encode_text( & input) ) ) ;
172
+ let is_match = if the_regex. is_match ( & input) { "true" } else { "false" } ;
173
+ html. push_str ( & format ! ( "\t \t \t <td>{}</td>\n " , is_match) ) ;
174
+ html. push_str ( "\t \t </tr>\n " ) ;
175
+ }
176
+
177
+ html. push_str ( "\t </tbody>\n " ) ;
178
+ html. push_str ( "</table>" ) ;
179
+
180
+ return handle_jsonp ( & test_input. callback , html) ;
181
+ }
182
+
183
+ fn handle_jsonp ( callback : & str , html : String ) -> Response < Body > {
184
+
185
+
186
+ let test_output = TestOutput {
187
+ success : true ,
188
+ message : "OK" . to_string ( ) ,
189
+ html : html,
190
+ } ;
191
+
192
+ let json_output = serde_json:: to_string ( & test_output) . unwrap ( ) ;
193
+
194
+ if callback == "" {
195
+ return Response :: builder ( )
196
+ . header ( "Content-Type" , "application/json; charset=utf-8" )
197
+ . body ( Body :: from ( json_output) )
198
+ . unwrap ( ) ;
199
+ } else {
200
+ let jsonp = format ! ( "{}({})" , callback, json_output) ;
201
+ return Response :: builder ( )
202
+ . header ( "Content-Type" , "text/html; charset=utf-8" )
203
+ . body ( Body :: from ( jsonp) )
204
+ . unwrap ( ) ;
205
+ }
92
206
}
0 commit comments