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