1- use std:: { path:: PathBuf , str :: FromStr } ;
1+ use std:: path:: PathBuf ;
22
3- use anyhow:: Result ;
3+ use anyhow:: { bail , Result } ;
44use iroh:: { protocol:: Router , Endpoint } ;
55use iroh_blobs:: {
66 net_protocol:: Blobs ,
7- rpc:: client:: blobs:: { ReadAtLen , WrapOption } ,
7+ rpc:: client:: blobs:: { self , WrapOption } ,
8+ store:: ExportMode ,
89 ticket:: BlobTicket ,
910 util:: SetTagOption ,
1011} ;
@@ -19,70 +20,103 @@ async fn main() -> Result<()> {
1920
2021 // Now we build a router that accepts blobs connections & routes them
2122 // to the blobs protocol.
22- let node = Router :: builder ( endpoint)
23+ let router = Router :: builder ( endpoint)
2324 . accept ( iroh_blobs:: ALPN , blobs. clone ( ) )
2425 . spawn ( )
2526 . await ?;
2627
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+ }
3334
34- println ! ( "Analyzing file." ) ;
35+ match & * args[ 0 ] {
36+ "send" => {
37+ send ( & router, blobs. client ( ) , & args) . await ?;
3538
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+ }
4149
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 ?;
4453
45- println ! ( "File analyzed. Fetch this file by running:" ) ;
46- println ! ( "cargo run --example transfer -- receive {ticket} {path}" ) ;
54+ Ok ( ( ) )
55+ }
4756
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 ( ) ?;
5360
54- println ! ( "Starting download ." ) ;
61+ println ! ( "Analyzing file ." ) ;
5562
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 ?;
6169
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 ) ? ;
6472
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+ }
6880
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" ) ;
8185 }
86+ let path_buf: PathBuf = args[ 1 ] . parse ( ) ?;
87+ let ticket: BlobTicket = args[ 2 ] . parse ( ) ?;
8288
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." ) ;
86109
87110 Ok ( ( ) )
88111}
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