1
1
// Copyright © 2021 Translucence Research, Inc. All rights reserved.
2
2
3
3
use crate :: routes:: {
4
- dispatch_url, dispatch_web_socket, RouteBinding , UrlSegmentType , UrlSegmentValue , Wallet ,
4
+ dispatch_url, dispatch_web_socket, BackendAdapter , MockBackendAdapter , RouteBinding ,
5
+ UrlSegmentType , UrlSegmentValue ,
5
6
} ;
6
7
use async_std:: {
7
8
sync:: { Arc , Mutex } ,
@@ -13,7 +14,7 @@ use std::str::FromStr;
13
14
use structopt:: StructOpt ;
14
15
use tide:: StatusCode ;
15
16
use tide_websockets:: { WebSocket , WebSocketConnection } ;
16
- use zerok_lib:: api:: server;
17
+ use zerok_lib:: { api:: server, wallet :: cape :: CapeWallet } ;
17
18
18
19
mod disco;
19
20
mod ip;
@@ -71,14 +72,27 @@ fn default_api_path() -> PathBuf {
71
72
[ & dir, Path :: new ( API_FILE ) ] . iter ( ) . collect ( )
72
73
}
73
74
74
- #[ derive( Clone ) ]
75
- pub struct WebState {
75
+ pub struct WebState < Adapter : BackendAdapter > {
76
76
web_path : PathBuf ,
77
77
api : toml:: Value ,
78
- wallet : Arc < Mutex < Option < Wallet > > > ,
78
+ wallet : Arc < Mutex < Option < CapeWallet < ' static , Adapter :: Backend > > > > ,
79
+ adapter : Adapter ,
79
80
}
80
81
81
- async fn form_demonstration ( req : tide:: Request < WebState > ) -> Result < tide:: Body , tide:: Error > {
82
+ impl < Adapter : BackendAdapter > Clone for WebState < Adapter > {
83
+ fn clone ( & self ) -> Self {
84
+ Self {
85
+ web_path : self . web_path . clone ( ) ,
86
+ api : self . api . clone ( ) ,
87
+ wallet : self . wallet . clone ( ) ,
88
+ adapter : self . adapter . clone ( ) ,
89
+ }
90
+ }
91
+ }
92
+
93
+ async fn form_demonstration (
94
+ req : tide:: Request < WebState < impl BackendAdapter > > ,
95
+ ) -> Result < tide:: Body , tide:: Error > {
82
96
let mut index_html: PathBuf = req. state ( ) . web_path . clone ( ) ;
83
97
index_html. push ( "index.html" ) ;
84
98
Ok ( tide:: Body :: from_file ( index_html) . await ?)
@@ -87,7 +101,7 @@ async fn form_demonstration(req: tide::Request<WebState>) -> Result<tide::Body,
87
101
// Get the route pattern that matches the URL of a request, and the bindings for parameters in the
88
102
// pattern. If no route matches, the error is a documentation string explaining what went wrong.
89
103
fn parse_route (
90
- req : & tide:: Request < WebState > ,
104
+ req : & tide:: Request < WebState < impl BackendAdapter > > ,
91
105
) -> Result < ( String , HashMap < String , RouteBinding > ) , String > {
92
106
let first_segment = & req
93
107
. url ( )
@@ -212,15 +226,17 @@ fn parse_route(
212
226
/// This function duplicates the logic for deciding which route was requested. This
213
227
/// is an unfortunate side-effect of defining the routes in an external file.
214
228
// todo !corbett Convert the error feedback into HTML
215
- async fn entry_page ( req : tide:: Request < WebState > ) -> Result < tide:: Response , tide:: Error > {
229
+ async fn entry_page (
230
+ req : tide:: Request < WebState < impl BackendAdapter > > ,
231
+ ) -> Result < tide:: Response , tide:: Error > {
216
232
match parse_route ( & req) {
217
233
Ok ( ( pattern, bindings) ) => dispatch_url ( req, pattern. as_str ( ) , & bindings) . await ,
218
234
Err ( arg_doc) => Ok ( tide:: Response :: builder ( 200 ) . body ( arg_doc) . build ( ) ) ,
219
235
}
220
236
}
221
237
222
238
async fn handle_web_socket (
223
- req : tide:: Request < WebState > ,
239
+ req : tide:: Request < WebState < impl BackendAdapter > > ,
224
240
wsc : WebSocketConnection ,
225
241
) -> tide:: Result < ( ) > {
226
242
match parse_route ( & req) {
@@ -231,23 +247,25 @@ async fn handle_web_socket(
231
247
232
248
// This route is a demonstration of a form with a WebSocket connection
233
249
// for asynchronous updates. Once we have useful forms, this can go...
234
- fn add_form_demonstration ( web_server : & mut tide:: Server < WebState > ) {
250
+ fn add_form_demonstration ( web_server : & mut tide:: Server < WebState < impl ' static + BackendAdapter > > ) {
235
251
web_server
236
252
. at ( "/transfer/:id/:recipient/:amount" )
237
253
. with ( WebSocket :: new ( handle_web_socket) )
238
254
. get ( form_demonstration) ;
239
255
}
240
256
241
- fn init_server (
257
+ fn init_server < Adapter : ' static + BackendAdapter > (
242
258
api_path : PathBuf ,
243
259
web_path : PathBuf ,
244
260
port : u64 ,
261
+ adapter : Adapter ,
245
262
) -> std:: io:: Result < JoinHandle < std:: io:: Result < ( ) > > > {
246
263
let api = disco:: load_messages ( & api_path) ;
247
264
let mut web_server = tide:: with_state ( WebState {
248
265
web_path : web_path. clone ( ) ,
249
266
api : api. clone ( ) ,
250
267
wallet : Arc :: new ( Mutex :: new ( None ) ) ,
268
+ adapter,
251
269
} ) ;
252
270
web_server. with ( server:: trace) . with ( server:: add_error_body) ;
253
271
@@ -329,7 +347,14 @@ async fn main() -> Result<(), std::io::Error> {
329
347
330
348
// Use something different than the default Spectrum port (60000 vs 50000).
331
349
let port = std:: env:: var ( "PORT" ) . unwrap_or_else ( |_| String :: from ( "60000" ) ) ;
332
- init_server ( api_path, web_path, port. parse ( ) . unwrap ( ) ) ?. await ?;
350
+ // TODO replace the mock backend with a real backend.
351
+ init_server (
352
+ api_path,
353
+ web_path,
354
+ port. parse ( ) . unwrap ( ) ,
355
+ MockBackendAdapter :: default ( ) ,
356
+ ) ?
357
+ . await ?;
333
358
334
359
Ok ( ( ) )
335
360
}
@@ -380,7 +405,12 @@ mod tests {
380
405
// the server will continue running until the process is killed, even after the test
381
406
// ends. This is probably not so bad, since each test's server task should be idle once
382
407
// the test is over, and anyways I don't see a good way around it.
383
- init_server ( default_api_path ( ) , default_web_path ( ) , port) . unwrap ( ) ;
408
+ init_server :: < MockCapeBackend < ' static , LoaderMetadata > > (
409
+ default_api_path ( ) ,
410
+ default_web_path ( ) ,
411
+ port,
412
+ )
413
+ . unwrap ( ) ;
384
414
385
415
let client: surf:: Client = surf:: Config :: new ( )
386
416
. set_base_url ( Url :: parse ( & format ! ( "http://localhost:{}" , port) ) . unwrap ( ) )
0 commit comments