diff --git a/src/main.rs b/src/main.rs index 9ac5d0b..ed33190 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,8 +25,15 @@ struct Cli{ #[derive(Subcommand)] enum Commands{ - Download(AssetIDList), - Upload{path:std::path::PathBuf,asset_id:AssetID}, + Download(AssetIDFileMapBad), + Upload(AssetIDFileMapBad), +} + +//idk how to make this a list of key-value pairs +#[derive(Args)] +struct AssetIDFileMapBad{ + asset_ids:Vec, + files:Vec, } #[derive(Args)] @@ -34,11 +41,6 @@ struct PathBufList{ paths:Vec } -#[derive(Args)] -struct AssetIDList{ - asset_ids:Vec, -} - #[tokio::main] async fn main()->AResult<()>{ let cli=Cli::parse(); @@ -63,8 +65,8 @@ async fn main()->AResult<()>{ }; match cli.command{ - Commands::Download(asset_id_list)=>download_list(cookie,asset_id_list.asset_ids).await, - Commands::Upload{path,asset_id}=>upload_list(cookie,group,path,asset_id).await, + Commands::Download(asset_id_file_map)=>download_list(cookie,transpose_asset_id_file_map(asset_id_file_map)?).await, + Commands::Upload(asset_id_file_map)=>upload_list(cookie,group,transpose_asset_id_file_map(asset_id_file_map)?).await, } } @@ -96,7 +98,17 @@ fn maybe_gzip_decode(input:&mut R)->AResult>{ } } -async fn upload_list(_cookie:String,_owner:Owner,_path:std::path::PathBuf,_asset_id:AssetID)->AResult<()>{ +type AssetIDFileMap=Vec<(AssetID,std::path::PathBuf)>; + +fn transpose_asset_id_file_map(asset_id_file_map:AssetIDFileMapBad)->AResult{ + if asset_id_file_map.asset_ids.len()==asset_id_file_map.files.len(){ + Ok(asset_id_file_map.asset_ids.into_iter().zip(asset_id_file_map.files.into_iter()).collect()) + }else{ + Err(anyhow::Error::msg("Asset list did not match file list.")) + } +} + +async fn upload_list(cookie:String,owner:Owner,asset_id_file_map:AssetIDFileMap)->AResult<()>{ Ok(()) } @@ -108,24 +120,23 @@ fn read_readable(mut readable:impl Read)->AResult>{ Ok(contents) } -async fn download_list(cookie:String,asset_ids:Vec)->AResult<()>{ +async fn download_list(cookie:String,asset_id_file_map:AssetIDFileMap)->AResult<()>{ let client=reqwest::Client::new(); - futures::stream::iter(asset_ids) - .map(|asset_id|{ + futures::stream::iter(asset_id_file_map) + .map(|(asset_id,file)|{ let client=&client; let cookie=cookie.as_str(); async move{ let resp=client.get(format!("https://assetdelivery.roblox.com/v1/asset/?ID={}",asset_id)) .header("Cookie",cookie) .send().await?; - Ok((asset_id,resp.bytes().await?)) + Ok((file,resp.bytes().await?)) } }) .buffer_unordered(CONCURRENT_REQUESTS) .for_each(|b:AResult<_>|async{ match b{ - Ok((asset_id,body))=>{ - let dest=std::path::PathBuf::from(asset_id.to_string()); + Ok((dest,body))=>{ let contents=match maybe_gzip_decode(&mut std::io::Cursor::new(body)){ Ok(ReaderType::GZip(readable))=>read_readable(readable), Ok(ReaderType::Raw(readable))=>read_readable(readable),