roblox_api/api/assets/
v1.rs1use std::path::Path;
2
3use reqwest::{header::HeaderValue, multipart::Form};
4use serde::{Deserialize, Serialize};
5
6use crate::{DateTime, Error, client::Client};
7
8const URL: &str = "https://apis.roblox.com/assets/user-auth/v1";
9
10#[derive(Clone, Debug, Deserialize, Serialize)]
11pub enum AssetType {
12 Audio,
13 Decal,
14 Model,
15 Video,
16}
17
18#[derive(Clone, Debug, Deserialize, Serialize)]
19pub enum Creator {
20 #[serde(rename = "userId")]
21 UserId(String), #[serde(rename = "groupId")]
24 GroupId(String),
25}
26
27#[derive(Clone, Debug, Deserialize, Serialize)]
28pub struct CreationContext {
29 pub creator: Creator,
30 #[serde(rename = "expectedPrice")]
31 pub expected_price: Option<u64>,
32}
33
34#[derive(Clone, Debug, Deserialize)]
35pub struct ModerationResult {
36 #[serde(rename = "moderationState")]
37 pub state: String,
38}
39
40#[derive(Debug, Deserialize)]
41pub struct AssetUploadResponse {
42 pub path: String,
43 #[serde(rename = "assetId")]
45 pub id: String,
46 #[serde(rename = "displayName")]
47 pub title: String,
48 #[serde(rename = "assetType")]
49 pub asset_type: AssetType,
50 pub state: String,
51 #[serde(rename = "revisionId")]
52 pub revision_id: String,
53 #[serde(rename = "revisionCreateTime")]
54 pub revision_creation_time: DateTime,
55 #[serde(rename = "creationContext")]
56 pub creation_context: CreationContext,
57 #[serde(rename = "moderationResult")]
58 pub moderation_result: ModerationResult,
59}
60
61#[derive(Debug, Deserialize)]
62pub struct AssetUploadStatus {
63 pub path: String,
64 #[serde(rename = "operationId")]
65 pub operation_id: String,
66 #[serde(rename = "done")]
67 pub complete: bool,
68 pub response: Option<AssetUploadResponse>,
69}
70
71pub async fn upload(
73 client: &mut Client,
74 path: impl AsRef<Path>,
75 title: &str,
76 description: &str,
77 asset_type: AssetType,
78 creation_context: CreationContext,
79) -> Result<AssetUploadStatus, Error> {
80 let mut headers = client.requestor.default_headers.clone();
81 headers.insert("Accept", HeaderValue::from_str("*/*").unwrap());
82
83 #[derive(Clone, Debug, Deserialize, Serialize)]
84 struct Request<'a> {
85 #[serde(rename = "displayName")]
86 title: &'a str,
87 description: &'a str,
88 #[serde(rename = "assetType")]
89 asset_type: AssetType,
90 #[serde(rename = "creationContext")]
91 creation_context: CreationContext,
92 }
93
94 let request = serde_json::to_string(&Request {
95 title,
96 description,
97 asset_type,
98 creation_context,
99 })
100 .unwrap();
101
102 let result = client
103 .requestor
104 .client
105 .post(format!("{URL}/assets"))
106 .headers(headers)
107 .multipart(
108 Form::new()
109 .text("request", request)
110 .file("fileContent", &path)
111 .await
112 .unwrap(),
113 )
114 .send()
115 .await;
116
117 let response = client.validate_response(result).await?;
118 client
119 .requestor
120 .parse_json::<AssetUploadStatus>(response)
121 .await
122}
123
124pub async fn status(client: &mut Client, operation_id: &str) -> Result<AssetUploadStatus, Error> {
125 let result = client
126 .requestor
127 .client
128 .get(format!("{URL}/operations/{operation_id}"))
129 .headers(client.requestor.default_headers.clone())
130 .send()
131 .await;
132
133 let response = client.validate_response(result).await?;
134 client
135 .requestor
136 .parse_json::<AssetUploadStatus>(response)
137 .await
138}