1
+ use std:: fs:: metadata;
2
+ use std:: path:: { Path , PathBuf } ;
3
+
1
4
use crate :: AResult ;
5
+ use anyhow:: anyhow;
2
6
use clap:: Parser ;
3
7
use clap:: { crate_authors, crate_description, crate_name, crate_version} ;
4
8
use tokio:: sync:: oneshot;
9
+ use tracing:: { debug, info} ;
5
10
6
11
use crate :: { generate_magic_string, recv_file, recv_msg, send_file, send_msg} ;
7
12
@@ -10,38 +15,68 @@ use crate::{generate_magic_string, recv_file, recv_msg, send_file, send_msg};
10
15
pub enum App {
11
16
Send {
12
17
file_path : String ,
13
- opt_magic_string : Option < String > ,
18
+ magic_string : Option < String > ,
14
19
} ,
15
20
Recv {
16
21
magic_string : String ,
22
+ save_dir : Option < PathBuf > ,
17
23
} ,
18
24
}
19
25
20
26
impl App {
21
27
pub async fn run ( & self ) -> AResult < ( ) > {
28
+ debug ! ( "{self:?}" ) ;
22
29
match self {
23
30
App :: Send {
24
- opt_magic_string ,
31
+ magic_string ,
25
32
file_path,
26
33
} => {
27
- let magic_string = opt_magic_string
34
+ let magic_string = magic_string
28
35
. to_owned ( )
29
36
. unwrap_or_else ( generate_magic_string) ;
30
- println ! ( "MAGIC -> {magic_string}" ) ;
37
+
38
+ println ! ( "MAGIC: {magic_string}" ) ;
39
+
40
+ info ! ( "MAGIC: {magic_string}" ) ;
31
41
32
42
let ( tx, rx) = oneshot:: channel ( ) ;
33
- let port = send_file ( file_path, tx) . await ?;
43
+
44
+ let file_size = metadata ( file_path) ?. len ( ) ;
45
+
46
+ let port = send_file ( file_path, file_size, tx) . await ?;
47
+
34
48
send_msg (
35
49
& magic_string,
36
50
port,
37
- [ ( "name" . into ( ) , file_path. into ( ) ) ] . into ( ) ,
38
- rx,
39
- )
40
- . await ?;
51
+ [
52
+ ( "name" . into ( ) , file_path. into ( ) ) ,
53
+ ( "size" . into ( ) , file_size. to_string ( ) ) ,
54
+ ]
55
+ . into ( ) ,
56
+ ) ?;
57
+
58
+ rx. await ?;
41
59
}
42
- App :: Recv { magic_string } => {
60
+ App :: Recv {
61
+ magic_string,
62
+ save_dir,
63
+ } => {
43
64
let ( addrs, port, data) = recv_msg ( magic_string) ?;
44
- recv_file ( addrs. iter ( ) . next ( ) . unwrap ( ) , port, & data[ "name" ] ) . await ?;
65
+ let name = Path :: new ( & data[ "name" ] )
66
+ . file_name ( )
67
+ . and_then ( |x| x. to_str ( ) )
68
+ . ok_or_else ( || anyhow ! ( "Error while read filename" ) ) ?;
69
+ let path = save_dir. clone ( ) . unwrap_or_else ( PathBuf :: new) . join ( name) ;
70
+ for addr in & addrs {
71
+ debug ! ( "Trying {addr}" ) ;
72
+ if recv_file ( addr, port, & path, data[ "size" ] . parse ( ) ?)
73
+ . await
74
+ . is_ok ( )
75
+ {
76
+ debug ! ( "File is received. Breaking loop" ) ;
77
+ break ;
78
+ }
79
+ }
45
80
}
46
81
}
47
82
Ok ( ( ) )
0 commit comments