1- use std:: { collections:: HashMap , path:: PathBuf } ;
2-
31use base64:: { Engine as _, engine:: general_purpose} ;
42use rocket:: { get, post, serde:: json:: Json } ;
53use serde:: Serialize ;
@@ -14,9 +12,16 @@ use crate::{
1412 utils:: s3:: { download_object, upload_object} ,
1513} ;
1614
15+ #[ derive( serde:: Deserialize ) ]
16+ pub struct V1SaveUploadFile {
17+ pub hash : String ,
18+ pub path : String ,
19+ pub content : String ,
20+ }
21+
1722#[ derive( serde:: Deserialize ) ]
1823pub struct V1SaveUploadRequest {
19- pub files : HashMap < String , String > ,
24+ pub files : Vec < V1SaveUploadFile > ,
2025}
2126
2227#[ post( "/api/v1/roms/<id>/save/<version_id>" , data = "<data>" ) ]
@@ -26,18 +31,26 @@ pub async fn upload_save(
2631 data : Json < V1SaveUploadRequest > ,
2732 user : AuthenticatedUser ,
2833) -> V1ApiResponseType < ( ) > {
29- for ( file_name, b64_content) in data. files . iter ( ) {
30- let buffer = general_purpose:: STANDARD . decode ( b64_content) . map_err ( |e| {
31- error ! ( "Failed to decode base64 for file '{}': {:?}" , file_name, e) ;
32- V1ApiError :: BadRequest
33- } ) ?;
34-
35- let save_path = format ! ( "/saves/{}/{}/{}/{}" , user. id. value( ) , id, version_id, file_name) ;
34+ for file in data. files . iter ( ) {
35+ let buffer = general_purpose:: STANDARD
36+ . decode ( & file. content )
37+ . map_err ( |e| {
38+ error ! ( "Failed to decode base64 for file '{}': {:?}" , file. path, e) ;
39+ V1ApiError :: BadRequest
40+ } ) ?;
41+
42+ let save_path = format ! (
43+ "/saves/{}/{}/{}/{}" ,
44+ user. id. value( ) ,
45+ id,
46+ version_id,
47+ file. hash
48+ ) ;
3649
3750 upload_object ( & save_path, & buffer) . await . map_err ( |e| {
3851 error ! (
3952 "Failed to upload save file '{}' to '{}': {:?}" ,
40- file_name , save_path, e
53+ file . path , save_path, e
4154 ) ;
4255 V1ApiError :: InternalError
4356 } ) ?;
@@ -51,15 +64,15 @@ pub async fn upload_save(
5164 user. id. value( ) ,
5265 id,
5366 version_id,
54- file_name ,
67+ file . path ,
5568 save_path
5669 )
5770 . execute ( & * SQL )
5871 . await
5972 . map_err ( |e| {
6073 error ! (
6174 "Database error inserting save file '{}': {:?}" ,
62- file_name , e
75+ file . path , e
6376 ) ;
6477 V1ApiError :: InternalError
6578 } ) ?;
@@ -68,14 +81,19 @@ pub async fn upload_save(
6881 Ok ( V1ApiResponse ( ( ) ) )
6982}
7083
71- #[ get( "/api/v1/roms/<id>/save/<version_id>/<file_name>" , rank = 1 ) ]
84+ #[ derive( serde:: Deserialize ) ]
85+ pub struct V1SaveDownloadRequest {
86+ pub path : String ,
87+ }
88+
89+ #[ post( "/api/v1/roms/<id>/save/<version_id>/download" , data = "<data>" ) ]
7290pub async fn download_save_file (
7391 id : String ,
7492 version_id : i64 ,
75- file_name : PathBuf ,
93+ data : Json < V1SaveDownloadRequest > ,
7694 user : AuthenticatedUser ,
7795) -> Result < Vec < u8 > , V1ApiError > {
78- let file_name_str = file_name . to_str ( ) . ok_or ( V1ApiError :: BadRequest ) ? ;
96+ let file_name_str = & data . path ;
7997
8098 let record = sqlx:: query!(
8199 "SELECT save_path FROM user_save_files
0 commit comments