roblox_api/api/inventory/
v2.rs

1use serde::Deserialize;
2
3use crate::{AssetTypeId, DateTime, Error, Paging, client::Client};
4
5pub const URL: &str = "https://inventory.roblox.com/v2";
6
7#[derive(Clone, Debug, Deserialize)]
8pub struct FromOwnerAssetOwner {
9    pub id: u64,
10    #[serde(rename = "type")]
11    pub kind: u64,
12    pub name: String,
13}
14
15#[derive(Clone, Debug, Deserialize)]
16pub struct FromOwnerAssetInfo {
17    pub id: u64,
18    #[serde(rename = "serialNumber")]
19    pub serial: u64,
20    #[serde(rename = "collectibleItemInstanceId")]
21    pub collectible_instance_id: Option<String>,
22    pub owner: UserOwnedAssetOwner,
23    pub created: DateTime,
24    pub updated: DateTime,
25}
26
27#[derive(Clone, Debug, Deserialize)]
28pub struct UserOwnedAssetOwner {
29    #[serde(rename = "userId")]
30    pub id: u64,
31    #[serde(rename = "buildersClubMembershipType")]
32    pub premium_membership_type: String,
33    #[serde(rename = "username")]
34    pub name: String,
35}
36
37#[derive(Clone, Debug, Deserialize)]
38pub struct UserOwnedAssetInfo {
39    #[serde(rename = "assetId")]
40    pub id: u64,
41    #[serde(rename = "userAssetId")]
42    pub instance_id: u64,
43    #[serde(rename = "assetName")]
44    pub name: String,
45    pub owner: UserOwnedAssetOwner,
46    #[serde(rename = "collectibleItemId")]
47    pub collectible_id: Option<u64>,
48    #[serde(rename = "collectibleItemInstanceId")]
49    pub collectible_instance_id: Option<u64>,
50    #[serde(rename = "serialNumber")]
51    pub serial: Option<u64>,
52    pub created: DateTime,
53    pub updated: DateTime,
54}
55
56#[derive(Clone, Debug, Deserialize)]
57pub struct UserOwnedAssets {
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<UserOwnedAssetInfo>,
64}
65
66#[derive(Clone, Debug, Deserialize)]
67pub struct AssetOwners {
68    #[serde(rename = "nextPageCursor")]
69    pub next_cursor: String,
70    #[serde(rename = "previousPageCursor")]
71    pub previous_cursor: String,
72    #[serde(rename = "data")]
73    pub assets: Vec<FromOwnerAssetInfo>,
74}
75
76pub async fn asset_owners(
77    client: &mut Client,
78    id: u64,
79    paging: Paging<'_>,
80) -> Result<AssetOwners, Error> {
81    let limit = paging.limit.unwrap_or(10);
82    let sort_order = paging.order.unwrap_or_default().to_string();
83    let cursor = match paging.cursor {
84        Some(cursor) => format!("&cursor={cursor}"),
85        None => String::new(),
86    };
87
88    let result = client
89        .requestor
90        .client
91        .get(format!(
92            "{URL}/assets/{id}/owners?limit={limit}&sortOrder={sort_order}{cursor}"
93        ))
94        .headers(client.requestor.default_headers.clone())
95        .send()
96        .await;
97
98    let response = client.validate_response(result).await?;
99    client.requestor.parse_json::<AssetOwners>(response).await
100}
101
102pub async fn user_owned_assets(
103    client: &mut Client,
104    user_id: u64,
105    asset_type_id: AssetTypeId,
106    paging: Paging<'_>,
107) -> Result<UserOwnedAssets, Error> {
108    let asset_type_id = asset_type_id as u8;
109
110    let limit = paging.limit.unwrap_or(10);
111    let sort_order = paging.order.unwrap_or_default().to_string();
112    let cursor = match paging.cursor {
113        Some(cursor) => format!("&cursor={cursor}"),
114        None => String::new(),
115    };
116
117    let result = client
118        .requestor
119        .client
120        .get(format!("{URL}/users/{user_id}/inventory/{asset_type_id}?limit={limit}&sortOrder={sort_order}{cursor}"))
121        .headers(client.requestor.default_headers.clone())
122        .send()
123        .await;
124
125    let response = client.validate_response(result).await?;
126    client
127        .requestor
128        .parse_json::<UserOwnedAssets>(response)
129        .await
130}