@@ -34,13 +34,19 @@ enum MetaRequest {
3434 Put { filename : String , hash : Hash } ,
3535 Get { filename : String } ,
3636 List ,
37+ Delete { filename : String } ,
38+ Rename { from : String , to : String } ,
39+ Copy { from : String , to : String } ,
3740}
3841
3942#[ derive( Debug , Serialize , Deserialize ) ]
4043enum MetaResponse {
4144 Put { success : bool } ,
4245 Get { hash : Option < Hash > } ,
4346 List { items : Vec < ( Hash , String ) > } ,
47+ Delete { success : bool } ,
48+ Rename { success : bool } ,
49+ Copy { success : bool } ,
4450}
4551
4652#[ derive( Clone , Debug ) ]
@@ -119,6 +125,40 @@ impl ProtocolHandler for MetaProtocol {
119125 send. write_all ( & resp) . await . map_err ( AcceptError :: from_err) ?;
120126 send. finish ( ) ?;
121127 }
128+ MetaRequest :: Delete { filename } => {
129+ let success = self . store . tags ( ) . delete ( & filename) . await . is_ok ( ) ;
130+ let resp = postcard:: to_allocvec ( & MetaResponse :: Delete { success } )
131+ . map_err ( AcceptError :: from_err) ?;
132+ send. write_all ( & resp) . await . map_err ( AcceptError :: from_err) ?;
133+ send. finish ( ) ?;
134+ }
135+ MetaRequest :: Rename { from, to } => {
136+ let success = if let Ok ( Some ( tag) ) = self . store . tags ( ) . get ( & from) . await {
137+ let hash = tag. hash ;
138+ if self . store . tags ( ) . set ( & to, hash) . await . is_ok ( ) {
139+ self . store . tags ( ) . delete ( & from) . await . is_ok ( )
140+ } else {
141+ false
142+ }
143+ } else {
144+ false
145+ } ;
146+ let resp = postcard:: to_allocvec ( & MetaResponse :: Rename { success } )
147+ . map_err ( AcceptError :: from_err) ?;
148+ send. write_all ( & resp) . await . map_err ( AcceptError :: from_err) ?;
149+ send. finish ( ) ?;
150+ }
151+ MetaRequest :: Copy { from, to } => {
152+ let success = if let Ok ( Some ( tag) ) = self . store . tags ( ) . get ( & from) . await {
153+ self . store . tags ( ) . set ( & to, tag. hash ) . await . is_ok ( )
154+ } else {
155+ false
156+ } ;
157+ let resp = postcard:: to_allocvec ( & MetaResponse :: Copy { success } )
158+ . map_err ( AcceptError :: from_err) ?;
159+ send. write_all ( & resp) . await . map_err ( AcceptError :: from_err) ?;
160+ send. finish ( ) ?;
161+ }
122162 }
123163 }
124164 Ok ( ( ) )
@@ -569,6 +609,94 @@ impl ReplContext {
569609 Ok ( ( ) )
570610 }
571611
612+ async fn delete ( & mut self , name : & str ) -> Result < ( ) > {
613+ if matches ! ( & self . inner, ReplContextInner :: Remote { .. } ) {
614+ let meta_conn = self . meta_conn ( ) . await ?;
615+ let ( mut send, mut recv) = meta_conn. open_bi ( ) . await ?;
616+ let req = postcard:: to_allocvec ( & MetaRequest :: Delete {
617+ filename : name. to_string ( ) ,
618+ } ) ?;
619+ send. write_all ( & req) . await ?;
620+ send. finish ( ) ?;
621+ let resp_buf = recv. read_to_end ( 64 * 1024 ) . await ?;
622+ let resp: MetaResponse = postcard:: from_bytes ( & resp_buf) ?;
623+
624+ match resp {
625+ MetaResponse :: Delete { success : true } => println ! ( "deleted: {}" , name) ,
626+ MetaResponse :: Delete { success : false } => bail ! ( "not found: {}" , name) ,
627+ _ => bail ! ( "unexpected response" ) ,
628+ }
629+ } else if let ReplContextInner :: Local { store } = & self . inner {
630+ let store_handle = store. as_store ( ) ;
631+ store_handle. tags ( ) . delete ( name) . await ?;
632+ println ! ( "deleted: {}" , name) ;
633+ }
634+ Ok ( ( ) )
635+ }
636+
637+ async fn rename ( & mut self , from : & str , to : & str ) -> Result < ( ) > {
638+ if matches ! ( & self . inner, ReplContextInner :: Remote { .. } ) {
639+ let meta_conn = self . meta_conn ( ) . await ?;
640+ let ( mut send, mut recv) = meta_conn. open_bi ( ) . await ?;
641+ let req = postcard:: to_allocvec ( & MetaRequest :: Rename {
642+ from : from. to_string ( ) ,
643+ to : to. to_string ( ) ,
644+ } ) ?;
645+ send. write_all ( & req) . await ?;
646+ send. finish ( ) ?;
647+ let resp_buf = recv. read_to_end ( 64 * 1024 ) . await ?;
648+ let resp: MetaResponse = postcard:: from_bytes ( & resp_buf) ?;
649+
650+ match resp {
651+ MetaResponse :: Rename { success : true } => println ! ( "renamed: {} -> {}" , from, to) ,
652+ MetaResponse :: Rename { success : false } => bail ! ( "not found: {}" , from) ,
653+ _ => bail ! ( "unexpected response" ) ,
654+ }
655+ } else if let ReplContextInner :: Local { store } = & self . inner {
656+ let store_handle = store. as_store ( ) ;
657+ let tag = store_handle
658+ . tags ( )
659+ . get ( from)
660+ . await ?
661+ . ok_or_else ( || anyhow ! ( "not found: {}" , from) ) ?;
662+ store_handle. tags ( ) . set ( to, tag. hash ) . await ?;
663+ store_handle. tags ( ) . delete ( from) . await ?;
664+ println ! ( "renamed: {} -> {}" , from, to) ;
665+ }
666+ Ok ( ( ) )
667+ }
668+
669+ async fn copy ( & mut self , from : & str , to : & str ) -> Result < ( ) > {
670+ if matches ! ( & self . inner, ReplContextInner :: Remote { .. } ) {
671+ let meta_conn = self . meta_conn ( ) . await ?;
672+ let ( mut send, mut recv) = meta_conn. open_bi ( ) . await ?;
673+ let req = postcard:: to_allocvec ( & MetaRequest :: Copy {
674+ from : from. to_string ( ) ,
675+ to : to. to_string ( ) ,
676+ } ) ?;
677+ send. write_all ( & req) . await ?;
678+ send. finish ( ) ?;
679+ let resp_buf = recv. read_to_end ( 64 * 1024 ) . await ?;
680+ let resp: MetaResponse = postcard:: from_bytes ( & resp_buf) ?;
681+
682+ match resp {
683+ MetaResponse :: Copy { success : true } => println ! ( "copied: {} -> {}" , from, to) ,
684+ MetaResponse :: Copy { success : false } => bail ! ( "not found: {}" , from) ,
685+ _ => bail ! ( "unexpected response" ) ,
686+ }
687+ } else if let ReplContextInner :: Local { store } = & self . inner {
688+ let store_handle = store. as_store ( ) ;
689+ let tag = store_handle
690+ . tags ( )
691+ . get ( from)
692+ . await ?
693+ . ok_or_else ( || anyhow ! ( "not found: {}" , from) ) ?;
694+ store_handle. tags ( ) . set ( to, tag. hash ) . await ?;
695+ println ! ( "copied: {} -> {}" , from, to) ;
696+ }
697+ Ok ( ( ) )
698+ }
699+
572700 async fn shutdown ( self ) -> Result < ( ) > {
573701 match self . inner {
574702 ReplContextInner :: Remote {
@@ -641,6 +769,9 @@ async fn run_repl() -> Result<()> {
641769 ) ;
642770 println ! ( " cat <NAME> - Print file to stdout" ) ;
643771 println ! ( " gethash <HASH> <OUTPUT> - Retrieve by hash (- for stdout)" ) ;
772+ println ! ( " delete <NAME> - Delete a file (alias: rm)" ) ;
773+ println ! ( " rename <FROM> <TO> - Rename a file" ) ;
774+ println ! ( " copy <FROM> <TO> - Copy a file (alias: cp)" ) ;
644775 println ! ( " !<cmd> - Run shell command" ) ;
645776 println ! ( " help - Show this help" ) ;
646777 println ! ( " quit - Exit repl" ) ;
@@ -653,6 +784,9 @@ async fn run_repl() -> Result<()> {
653784 [ "get" , name, output] => ctx. get ( name, Some ( output) ) . await ,
654785 [ "cat" , name] => ctx. get ( name, Some ( "-" ) ) . await ,
655786 [ "gethash" , hash, output] => ctx. gethash ( hash, output) . await ,
787+ [ "delete" , name] | [ "rm" , name] => ctx. delete ( name) . await ,
788+ [ "rename" , from, to] => ctx. rename ( from, to) . await ,
789+ [ "copy" , from, to] | [ "cp" , from, to] => ctx. copy ( from, to) . await ,
656790 _ => {
657791 println ! ( "unknown command: {}" , line) ;
658792 println ! ( "type 'help' for available commands" ) ;
0 commit comments