Create multiple assets concurrently #5
@ -14,26 +14,27 @@ pub struct CreateAssetRequest{
|
|||||||
pub displayName:String,
|
pub displayName:String,
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CreateAssetResponseGetAssetError{
|
pub enum AssetOperationError{
|
||||||
Operation(OperationError),
|
Operation(OperationError),
|
||||||
Serialize(serde_json::Error),
|
Serialize(serde_json::Error),
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for CreateAssetResponseGetAssetError{
|
impl std::fmt::Display for AssetOperationError{
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
write!(f,"{self:?}")
|
write!(f,"{self:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::error::Error for CreateAssetResponseGetAssetError{}
|
impl std::error::Error for AssetOperationError{}
|
||||||
pub struct CreateAssetResponse{
|
#[derive(Debug)]
|
||||||
|
pub struct AssetOperation{
|
||||||
operation:RobloxOperation,
|
operation:RobloxOperation,
|
||||||
}
|
}
|
||||||
impl CreateAssetResponse{
|
impl AssetOperation{
|
||||||
pub async fn try_get_asset(&self,context:&CloudContext)->Result<AssetResponse,CreateAssetResponseGetAssetError>{
|
pub async fn try_get_asset(&self,context:&CloudContext)->Result<AssetResponse,AssetOperationError>{
|
||||||
serde_json::from_value(
|
serde_json::from_value(
|
||||||
self.operation
|
self.operation
|
||||||
.try_get_reponse(context).await
|
.try_get_reponse(context).await
|
||||||
.map_err(CreateAssetResponseGetAssetError::Operation)?
|
.map_err(AssetOperationError::Operation)?
|
||||||
).map_err(CreateAssetResponseGetAssetError::Serialize)
|
).map_err(AssetOperationError::Serialize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -111,8 +112,8 @@ impl std::fmt::Display for UpdateError{
|
|||||||
}
|
}
|
||||||
impl std::error::Error for UpdateError{}
|
impl std::error::Error for UpdateError{}
|
||||||
|
|
||||||
pub struct GetAssetOperationRequest{
|
struct GetAssetOperationRequest{
|
||||||
pub operation_id:String,
|
operation_id:String,
|
||||||
}
|
}
|
||||||
pub struct GetAssetInfoRequest{
|
pub struct GetAssetInfoRequest{
|
||||||
pub asset_id:u64,
|
pub asset_id:u64,
|
||||||
@ -260,7 +261,7 @@ impl std::fmt::Display for OperationError{
|
|||||||
impl std::error::Error for OperationError{}
|
impl std::error::Error for OperationError{}
|
||||||
#[derive(Debug,serde::Deserialize,serde::Serialize)]
|
#[derive(Debug,serde::Deserialize,serde::Serialize)]
|
||||||
#[allow(nonstandard_style,dead_code)]
|
#[allow(nonstandard_style,dead_code)]
|
||||||
pub struct RobloxOperation{
|
struct RobloxOperation{
|
||||||
pub path:Option<String>,
|
pub path:Option<String>,
|
||||||
pub metadata:Option<String>,
|
pub metadata:Option<String>,
|
||||||
pub done:Option<bool>,
|
pub done:Option<bool>,
|
||||||
@ -354,7 +355,7 @@ impl CloudContext{
|
|||||||
.multipart(form)
|
.multipart(form)
|
||||||
.send().await
|
.send().await
|
||||||
}
|
}
|
||||||
pub async fn create_asset(&self,config:CreateAssetRequest,body:impl Into<std::borrow::Cow<'static,[u8]>>)->Result<CreateAssetResponse,CreateError>{
|
pub async fn create_asset(&self,config:CreateAssetRequest,body:impl Into<std::borrow::Cow<'static,[u8]>>)->Result<AssetOperation,CreateError>{
|
||||||
let url=reqwest::Url::parse("https://apis.roblox.com/assets/v1/assets").map_err(CreateError::Parse)?;
|
let url=reqwest::Url::parse("https://apis.roblox.com/assets/v1/assets").map_err(CreateError::Parse)?;
|
||||||
|
|
||||||
let request_config=serde_json::to_string(&config).map_err(CreateError::Serialize)?;
|
let request_config=serde_json::to_string(&config).map_err(CreateError::Serialize)?;
|
||||||
@ -367,15 +368,16 @@ impl CloudContext{
|
|||||||
.text("request",request_config)
|
.text("request",request_config)
|
||||||
.part("fileContent",part);
|
.part("fileContent",part);
|
||||||
|
|
||||||
let operation=self.post_form(url,form).await.map_err(CreateError::Reqwest)?
|
let operation=self.post_form(url,form).await
|
||||||
|
.map_err(CreateError::Reqwest)?
|
||||||
.error_for_status().map_err(CreateError::Reqwest)?
|
.error_for_status().map_err(CreateError::Reqwest)?
|
||||||
.json::<RobloxOperation>().await.map_err(CreateError::Reqwest)?;
|
.json::<RobloxOperation>().await.map_err(CreateError::Reqwest)?;
|
||||||
|
|
||||||
Ok(CreateAssetResponse{
|
Ok(AssetOperation{
|
||||||
operation,
|
operation,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub async fn update_asset(&self,config:UpdateAssetRequest,body:impl Into<std::borrow::Cow<'static,[u8]>>)->Result<RobloxOperation,UpdateError>{
|
pub async fn update_asset(&self,config:UpdateAssetRequest,body:impl Into<std::borrow::Cow<'static,[u8]>>)->Result<AssetOperation,UpdateError>{
|
||||||
let raw_url=format!("https://apis.roblox.com/assets/v1/assets/{}",config.assetId);
|
let raw_url=format!("https://apis.roblox.com/assets/v1/assets/{}",config.assetId);
|
||||||
let url=reqwest::Url::parse(raw_url.as_str()).map_err(UpdateError::ParseError)?;
|
let url=reqwest::Url::parse(raw_url.as_str()).map_err(UpdateError::ParseError)?;
|
||||||
|
|
||||||
@ -385,13 +387,17 @@ impl CloudContext{
|
|||||||
.text("request",request_config)
|
.text("request",request_config)
|
||||||
.part("fileContent",reqwest::multipart::Part::bytes(body));
|
.part("fileContent",reqwest::multipart::Part::bytes(body));
|
||||||
|
|
||||||
self.patch_form(url,form).await
|
let operation=self.patch_form(url,form).await
|
||||||
.map_err(UpdateError::Reqwest)?
|
.map_err(UpdateError::Reqwest)?
|
||||||
//roblox api documentation is very poor, just give the status code and drop the json
|
//roblox api documentation is very poor, just give the status code and drop the json
|
||||||
.error_for_status().map_err(UpdateError::Reqwest)?
|
.error_for_status().map_err(UpdateError::Reqwest)?
|
||||||
.json::<RobloxOperation>().await.map_err(UpdateError::Reqwest)
|
.json::<RobloxOperation>().await.map_err(UpdateError::Reqwest)?;
|
||||||
|
|
||||||
|
Ok(AssetOperation{
|
||||||
|
operation,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
pub async fn get_asset_operation(&self,config:GetAssetOperationRequest)->Result<RobloxOperation,GetError>{
|
async fn get_asset_operation(&self,config:GetAssetOperationRequest)->Result<RobloxOperation,GetError>{
|
||||||
let raw_url=format!("https://apis.roblox.com/assets/v1/operations/{}",config.operation_id);
|
let raw_url=format!("https://apis.roblox.com/assets/v1/operations/{}",config.operation_id);
|
||||||
let url=reqwest::Url::parse(raw_url.as_str()).map_err(GetError::ParseError)?;
|
let url=reqwest::Url::parse(raw_url.as_str()).map_err(GetError::ParseError)?;
|
||||||
|
|
||||||
|
14
src/main.rs
14
src/main.rs
@ -624,13 +624,13 @@ struct CreateAssetMediaConfig{
|
|||||||
|
|
||||||
async fn get_asset_exp_backoff(
|
async fn get_asset_exp_backoff(
|
||||||
context:&CloudContext,
|
context:&CloudContext,
|
||||||
create_asset_response:&rbx_asset::cloud::CreateAssetResponse
|
asset_operation:&rbx_asset::cloud::AssetOperation
|
||||||
)->Result<rbx_asset::cloud::AssetResponse,rbx_asset::cloud::CreateAssetResponseGetAssetError>{
|
)->Result<rbx_asset::cloud::AssetResponse,rbx_asset::cloud::AssetOperationError>{
|
||||||
let mut backoff:u16=0;
|
let mut backoff:u16=0;
|
||||||
loop{
|
loop{
|
||||||
match create_asset_response.try_get_asset(&context).await{
|
match asset_operation.try_get_asset(&context).await{
|
||||||
//try again when the operation is not done
|
//try again when the operation is not done
|
||||||
Err(rbx_asset::cloud::CreateAssetResponseGetAssetError::Operation(rbx_asset::cloud::OperationError::NotDone))=>(),
|
Err(rbx_asset::cloud::AssetOperationError::Operation(rbx_asset::cloud::OperationError::NotDone))=>(),
|
||||||
//return all other results
|
//return all other results
|
||||||
other_result=>return other_result,
|
other_result=>return other_result,
|
||||||
}
|
}
|
||||||
@ -690,7 +690,7 @@ impl std::error::Error for CreateAssetMediasError{}
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
enum PollOperationError{
|
enum PollOperationError{
|
||||||
CreateAssetMedias(CreateAssetMediasError),
|
CreateAssetMedias(CreateAssetMediasError),
|
||||||
CreateAssetResponseGetAsset(rbx_asset::cloud::CreateAssetResponseGetAssetError),
|
AssetOperation(rbx_asset::cloud::AssetOperationError),
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for PollOperationError{
|
impl std::fmt::Display for PollOperationError{
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
@ -762,8 +762,8 @@ async fn create_asset_medias(config:CreateAssetMediasConfig)->AResult<()>{
|
|||||||
let context=&context;
|
let context=&context;
|
||||||
async{(path,
|
async{(path,
|
||||||
async{
|
async{
|
||||||
let create_asset_response=create_result.map_err(PollOperationError::CreateAssetMedias)?;
|
let asset_operation=create_result.map_err(PollOperationError::CreateAssetMedias)?;
|
||||||
get_asset_exp_backoff(context,&create_asset_response).await.map_err(PollOperationError::CreateAssetResponseGetAsset)
|
get_asset_exp_backoff(context,&asset_operation).await.map_err(PollOperationError::AssetOperation)
|
||||||
}
|
}
|
||||||
.await)}
|
.await)}
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user