roblox_api/api/inventory/
v1.rs1use serde::{Deserialize, Serialize};
2
3use crate::{AssetTypeId, Error, Paging, client::Client};
4
5pub const URL: &str = "https://inventory.roblox.com/v1";
6
7#[repr(u8)]
8#[derive(Clone, Debug, Deserialize, Serialize)]
9pub enum ItemType {
10 Asset = 0,
11 Gamepass,
12 Badge,
13 Bundle,
14}
15
16#[derive(Clone, Debug, Deserialize, Serialize)]
17#[serde(rename_all = "camelCase")]
18pub struct AssetInfo {
19 pub id: u64,
20 #[serde(rename = "type")]
21 pub kind: String,
22 pub name: String,
23 pub instance_id: u64,
24}
25
26#[derive(Clone, Debug, Deserialize, Serialize)]
27pub struct UserOwnsAssets {
28 #[serde(rename = "nextPageCursor")]
29 pub next_cursor: Option<String>,
30 #[serde(rename = "previousPageCursor")]
31 pub previous_cursor: Option<String>,
32 #[serde(rename = "data")]
33 pub assets: Vec<AssetInfo>,
34}
35
36#[derive(Clone, Debug, Deserialize, Serialize)]
37#[serde(rename_all = "camelCase")]
38pub struct CollectibleInfo {
39 #[serde(rename = "assetId")]
40 pub id: u64,
41 pub original_price: u64,
42 pub recent_average_price: u64,
43 #[serde(rename = "assetStock")]
44 pub stock: u64,
45 #[serde(rename = "userAssetId")]
46 pub instance_id: u64,
47 pub name: String,
48 #[serde(rename = "buildersClubMembershipType")]
49 pub premium_membership_type: String,
50 #[serde(rename = "isOnHold")]
51 pub on_hold: bool,
52 #[serde(rename = "serialNumber")]
53 pub serial: Option<u64>,
54}
55
56#[derive(Clone, Debug, Deserialize, Serialize)]
57pub struct UserOwnedCollectibles {
58 #[serde(rename = "nextPageCursor")]
59 pub next_cursor: Option<String>,
60 #[serde(rename = "previousPageCursor")]
61 pub previous_cursor: Option<String>,
62 #[serde(rename = "data")]
63 pub assets: Vec<CollectibleInfo>,
64}
65
66pub async fn can_view_inventory(client: &mut Client, user_id: u64) -> Result<bool, Error> {
67 let result = client
68 .requestor
69 .client
70 .get(format!("{URL}/users/{user_id}/can-view-inventory"))
71 .headers(client.requestor.default_headers.clone())
72 .send()
73 .await;
74
75 #[derive(Clone, Debug, Deserialize)]
76 #[serde(rename_all = "camelCase")]
77 struct Response {
78 can_view: bool,
79 }
80
81 let response = client.validate_response(result).await?;
82 Ok(client
83 .requestor
84 .parse_json::<Response>(response)
85 .await?
86 .can_view)
87}
88
89pub async fn user_owns_assets(
90 client: &mut Client,
91 user_id: u64,
92 id: u64,
93 item_type: ItemType,
94 paging: Paging<'_>,
95) -> Result<UserOwnsAssets, Error> {
96 let item_type = item_type as u8;
97
98 let cursor = match paging.cursor {
99 Some(cursor) => cursor.to_string(),
100 None => String::new(),
101 };
102
103 let result = client
104 .requestor
105 .client
106 .get(format!("{URL}/users/{user_id}/items/{item_type}/{id}"))
107 .query(&[("cursor", cursor)])
108 .headers(client.requestor.default_headers.clone())
109 .send()
110 .await;
111
112 let response = client.validate_response(result).await?;
113 client
114 .requestor
115 .parse_json::<UserOwnsAssets>(response)
116 .await
117}
118
119pub async fn user_owned_collectibles(
120 client: &mut Client,
121 user_id: u64,
122 asset_type_id: Option<AssetTypeId>,
123 paging: Paging<'_>,
124) -> Result<UserOwnedCollectibles, Error> {
125 let limit = paging.limit.unwrap_or(10).to_string();
126 let sort_order = paging.order.unwrap_or_default().to_string();
127 let cursor = match paging.cursor {
128 Some(cursor) => cursor.to_string(),
129 None => String::new(),
130 };
131
132 let asset_type = match asset_type_id {
133 Some(id) => {
134 let id = id as u8;
135 id.to_string()
136 }
137 None => String::new(),
138 };
139
140 let result = client
141 .requestor
142 .client
143 .get(format!("{URL}/users/{user_id}/assets/collectibles"))
144 .query(&[
145 ("assetType", asset_type),
146 ("limit", limit),
147 ("sortOrder", sort_order),
148 ("cursor", cursor),
149 ])
150 .headers(client.requestor.default_headers.clone())
151 .send()
152 .await;
153
154 let response = client.validate_response(result).await?;
155 client
156 .requestor
157 .parse_json::<UserOwnedCollectibles>(response)
158 .await
159}