1
- use std:: { path:: PathBuf , str :: FromStr } ;
1
+ use std:: path:: PathBuf ;
2
2
3
- use anyhow:: Result ;
3
+ use anyhow:: { bail , Result } ;
4
4
use iroh:: { protocol:: Router , Endpoint } ;
5
5
use iroh_blobs:: {
6
6
net_protocol:: Blobs ,
7
- rpc:: client:: blobs:: { ReadAtLen , WrapOption } ,
7
+ rpc:: client:: blobs:: { self , WrapOption } ,
8
+ store:: ExportMode ,
8
9
ticket:: BlobTicket ,
9
10
util:: SetTagOption ,
10
11
} ;
@@ -19,70 +20,103 @@ async fn main() -> Result<()> {
19
20
20
21
// Now we build a router that accepts blobs connections & routes them
21
22
// to the blobs protocol.
22
- let node = Router :: builder ( endpoint)
23
+ let router = Router :: builder ( endpoint)
23
24
. accept ( iroh_blobs:: ALPN , blobs. clone ( ) )
24
25
. spawn ( )
25
26
. await ?;
26
27
27
- let blobs = blobs . client ( ) ;
28
-
29
- let args = std :: env :: args ( ) . collect :: < Vec < _ > > ( ) ;
30
- match & args . iter ( ) . map ( String :: as_str ) . collect :: < Vec < _ > > ( ) [ .. ] {
31
- [ _cmd , "send" , path ] => {
32
- let abs_path = PathBuf :: from_str ( path ) ? . canonicalize ( ) ? ;
28
+ // Grab all passed in arguments, the first one is the binary itself, so we skip it.
29
+ let args : Vec < _ > = std :: env :: args ( ) . skip ( 1 ) . collect ( ) ;
30
+ if args. len ( ) < 2 {
31
+ print_usage ( ) ;
32
+ bail ! ( "too few arguments" ) ;
33
+ }
33
34
34
- println ! ( "Analyzing file." ) ;
35
+ match & * args[ 0 ] {
36
+ "send" => {
37
+ send ( & router, blobs. client ( ) , & args) . await ?;
35
38
36
- let blob = blobs
37
- . add_from_path ( abs_path, true , SetTagOption :: Auto , WrapOption :: NoWrap )
38
- . await ?
39
- . finish ( )
40
- . await ?;
39
+ tokio:: signal:: ctrl_c ( ) . await ?;
40
+ }
41
+ "receive" => {
42
+ receive ( blobs. client ( ) , & args) . await ?;
43
+ }
44
+ cmd => {
45
+ print_usage ( ) ;
46
+ bail ! ( "unkown command {}" , cmd) ;
47
+ }
48
+ }
41
49
42
- let node_id = node. endpoint ( ) . node_id ( ) ;
43
- let ticket = BlobTicket :: new ( node_id. into ( ) , blob. hash , blob. format ) ?;
50
+ // Gracefully shut down the node
51
+ println ! ( "Shutting down." ) ;
52
+ router. shutdown ( ) . await ?;
44
53
45
- println ! ( "File analyzed. Fetch this file by running:" ) ;
46
- println ! ( "cargo run --example transfer -- receive {ticket} {path}" ) ;
54
+ Ok ( ( ) )
55
+ }
47
56
48
- tokio:: signal:: ctrl_c ( ) . await ?;
49
- }
50
- [ _cmd, "receive" , ticket, path] => {
51
- let path_buf = PathBuf :: from_str ( path) ?;
52
- let ticket = BlobTicket :: from_str ( ticket) ?;
57
+ async fn send ( router : & Router , blobs : & blobs:: MemClient , args : & [ String ] ) -> Result < ( ) > {
58
+ let path: PathBuf = args[ 1 ] . parse ( ) ?;
59
+ let abs_path = path. canonicalize ( ) ?;
53
60
54
- println ! ( "Starting download ." ) ;
61
+ println ! ( "Analyzing file ." ) ;
55
62
56
- blobs
57
- . download ( ticket. hash ( ) , ticket. node_addr ( ) . clone ( ) )
58
- . await ?
59
- . finish ( )
60
- . await ?;
63
+ // keep the file in place, and link it
64
+ let in_place = true ;
65
+ let blob = blobs
66
+ . add_from_path ( abs_path, in_place, SetTagOption :: Auto , WrapOption :: NoWrap )
67
+ . await ?
68
+ . await ?;
61
69
62
- println ! ( "Finished download." ) ;
63
- println ! ( "Copying to destination." ) ;
70
+ let node_id = router . endpoint ( ) . node_id ( ) ;
71
+ let ticket = BlobTicket :: new ( node_id . into ( ) , blob . hash , blob . format ) ? ;
64
72
65
- let mut file = tokio:: fs:: File :: create ( path_buf) . await ?;
66
- let mut reader = blobs. read_at ( ticket. hash ( ) , 0 , ReadAtLen :: All ) . await ?;
67
- tokio:: io:: copy ( & mut reader, & mut file) . await ?;
73
+ println ! ( "File analyzed. Fetch this file by running:" ) ;
74
+ println ! (
75
+ "cargo run --example transfer -- receive {ticket} {}" ,
76
+ path. display( )
77
+ ) ;
78
+ Ok ( ( ) )
79
+ }
68
80
69
- println ! ( "Finished copying." ) ;
70
- }
71
- _ => {
72
- println ! ( "Couldn't parse command line arguments." ) ;
73
- println ! ( "Usage:" ) ;
74
- println ! ( " # to send:" ) ;
75
- println ! ( " cargo run --example transfer -- send [FILE]" ) ;
76
- println ! ( " # this will print a ticket." ) ;
77
- println ! ( ) ;
78
- println ! ( " # to receive:" ) ;
79
- println ! ( " cargo run --example transfer -- receive [TICKET] [FILE]" ) ;
80
- }
81
+ async fn receive ( blobs : & blobs:: MemClient , args : & [ String ] ) -> Result < ( ) > {
82
+ if args. len ( ) < 3 {
83
+ print_usage ( ) ;
84
+ bail ! ( "too few arguments" ) ;
81
85
}
86
+ let path_buf: PathBuf = args[ 1 ] . parse ( ) ?;
87
+ let ticket: BlobTicket = args[ 2 ] . parse ( ) ?;
82
88
83
- // Gracefully shut down the node
84
- println ! ( "Shutting down." ) ;
85
- node. shutdown ( ) . await ?;
89
+ println ! ( "Starting download." ) ;
90
+
91
+ blobs
92
+ . download ( ticket. hash ( ) , ticket. node_addr ( ) . clone ( ) )
93
+ . await ?
94
+ . await ?;
95
+
96
+ println ! ( "Finished download." ) ;
97
+ println ! ( "Copying to destination." ) ;
98
+
99
+ blobs
100
+ . export (
101
+ ticket. hash ( ) ,
102
+ path_buf,
103
+ ticket. format ( ) . into ( ) ,
104
+ ExportMode :: Copy ,
105
+ )
106
+ . await ?;
107
+
108
+ println ! ( "Finished copying." ) ;
86
109
87
110
Ok ( ( ) )
88
111
}
112
+
113
+ fn print_usage ( ) {
114
+ println ! ( "Couldn't parse command line arguments." ) ;
115
+ println ! ( "Usage:" ) ;
116
+ println ! ( " # to send:" ) ;
117
+ println ! ( " cargo run --example transfer -- send [FILE]" ) ;
118
+ println ! ( " # this will print a ticket." ) ;
119
+ println ! ( ) ;
120
+ println ! ( " # to receive:" ) ;
121
+ println ! ( " cargo run --example transfer -- receive [TICKET] [FILE]" ) ;
122
+ }
0 commit comments