roblox_api/api/toolbox_service/
v1.rs1use serde::{Deserialize, Serialize};
2
3use crate::{AssetTypeId, DateTime, Error, Paging, client::Client};
4
5pub const URL: &str = "https://apis.roblox.com/toolbox-service/v1";
6
7#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
8pub struct CreationObject {
9 pub id: u64,
10 pub name: String,
11}
12
13#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
14#[serde(rename_all = "camelCase")]
15pub struct Creations {
16 #[serde(rename = "totalResults")]
17 pub results: u16,
18 pub filtered_keyword: String,
19 #[serde(rename = "data")]
20 pub objects: Vec<CreationObject>,
21}
22
23#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
24#[serde(rename_all = "camelCase")]
25pub struct ItemDetailAsset {
26 pub id: u64,
27 pub name: String,
28 pub description: String,
29 pub type_id: u32,
30 pub duration: u32,
31 #[serde(rename = "visibilityStatus")]
32 pub visibility: u32,
33 pub is_endorsed: bool,
34 pub has_scripts: bool,
35 pub is_asset_hash_approved: bool,
36 #[serde(rename = "createdUtc")]
37 pub created: DateTime,
38 #[serde(rename = "updatedUtc")]
39 pub updated: DateTime,
40 #[serde(rename = "assetGenres")]
46 pub genres: Vec<String>,
47}
48
49#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
50pub struct ItemDetailCreator {
51 pub id: u64,
52 pub name: String,
53 #[serde(rename = "type")]
54 pub kind: u64,
55 #[serde(rename = "isVerifiedCreator")]
56 pub is_verified: bool,
57}
58
59#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
60#[serde(rename_all = "camelCase")]
61pub struct ItemDetailVotes {
62 #[serde(rename = "upVotes")]
63 pub likes: u32,
64 #[serde(rename = "downVotes")]
65 pub dislikes: u32,
66 #[serde(rename = "voteCount")]
67 pub votes: u32,
68 #[serde(rename = "votePercent")]
69 pub like_ratio: f32,
70 pub show_votes: bool,
71 pub can_vote: bool,
72 pub has_voted: bool,
73}
74
75#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
76pub struct FiatProductPriceQuantity {
77 pub significand: u32,
78 pub exponent: u32,
79}
80
81#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
82#[serde(rename_all = "camelCase")]
83pub struct FiatProductPrice {
84 pub currency_code: String,
85 pub quantity: FiatProductPriceQuantity,
86}
87
88#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
89pub struct FiatProduct {
90 #[serde(rename = "purchasePrice")]
91 pub price: FiatProductPrice,
92 pub published: bool,
93 pub purchasable: bool,
94}
95
96#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
97#[serde(rename_all = "camelCase")]
98pub struct ItemDetail {
99 pub asset: ItemDetailAsset,
100 pub creator: ItemDetailCreator,
101 pub votes: ItemDetailVotes,
102 pub fiat_product: FiatProduct,
103}
104
105pub async fn item_details(client: &mut Client, ids: &[u64]) -> Result<Vec<ItemDetail>, Error> {
106 let ids = ids
107 .iter()
108 .map(|x| x.to_string())
109 .collect::<Vec<String>>()
110 .join(",");
111
112 let result = client
113 .requestor
114 .client
115 .get(format!("{URL}/items/details?assetIds={ids}"))
116 .headers(client.requestor.default_headers.clone())
117 .send()
118 .await;
119
120 #[derive(Clone, Debug, Deserialize, PartialEq)]
121 struct Response {
122 #[serde(rename = "data")]
123 objects: Vec<ItemDetail>,
124 }
125
126 let response = client.validate_response(result).await?;
127 Ok(client
128 .requestor
129 .parse_json::<Response>(response)
130 .await?
131 .objects)
132}
133
134pub async fn creations(
135 client: &mut Client,
136 id: u64,
137 asset_type: AssetTypeId,
138 paging: Paging<'_>,
139) -> Result<Creations, Error> {
140 let limit = paging.limit.unwrap_or(30);
141 let cursor = match paging.cursor {
142 Some(cursor) => format!("&cursor={cursor}"),
143 None => String::new(),
144 };
145
146 let result = client
147 .requestor
148 .client
149 .get(format!(
150 "{URL}/creations/user/{id}/{}?limit={limit}{cursor}",
151 asset_type as u8
152 ))
153 .headers(client.requestor.default_headers.clone())
154 .send()
155 .await;
156
157 let response = client.validate_response(result).await?;
158 client.requestor.parse_json::<Creations>(response).await
159}