1use serde::{Deserialize, Serialize};
2use strum_macros::{Display, EnumString};
3
4use crate::{DateTime, Paging, endpoint};
5
6pub const URL: &str = "https://badges.roblox.com/v1";
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq, Display, EnumString)]
9pub enum BadgeSortBy {
10 Rank,
11 DateCreated,
12}
13
14#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Display, EnumString)]
16pub enum BadgeCreatorType {
17 User,
18 Group,
19}
20
21#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Display, EnumString)]
22pub enum BadgeAwarderType {
23 Place,
24}
25
26#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
27#[serde(rename_all = "camelCase")]
28pub struct BadgeStatistics {
29 #[serde(rename = "pastDayAwardedCount")]
30 pub awarded_today: u32,
31 #[serde(rename = "awardedCount")]
32 pub awarded_total: u32,
33 pub win_rate_percentage: f32,
34}
35
36#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
37pub struct BadgeCreator {
38 pub id: u64,
39 pub name: String,
40 #[serde(rename = "type")]
41 pub kind: BadgeCreatorType,
42}
43
44#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
45pub struct BadgeAwarder {
46 pub id: u64,
47 #[serde(rename = "type")]
48 pub kind: BadgeAwarderType,
49}
50
51#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
52#[serde(rename_all = "camelCase")]
53pub struct BadgeUniverse {
54 pub id: u64,
55 pub name: String,
56 pub root_place_id: u64,
57}
58
59#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
60#[serde(rename_all = "camelCase")]
61pub struct Badge {
62 pub id: u64,
63 pub name: String,
64 pub description: String,
65
66 pub display_name: String,
67 pub display_description: String,
68
69 pub enabled: bool,
70
71 pub created: DateTime,
72 pub updated: DateTime,
73
74 pub icon_image_id: u64,
75 pub display_icon_image_id: u64,
76
77 pub statistics: BadgeStatistics,
78
79 pub creator: Option<BadgeCreator>,
80 pub awarder: Option<BadgeAwarder>,
81 #[serde(rename = "awardingUniverse")]
82 pub universe: Option<BadgeUniverse>,
83}
84
85#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
86pub struct BadgesResponse {
87 #[serde(rename = "data")]
88 pub badges: Vec<Badge>,
89 #[serde(rename = "nextPageCursor")]
90 pub next_cursor: Option<String>,
91 #[serde(rename = "previousPageCursor")]
92 pub previous_cursor: Option<String>,
93}
94
95endpoint! {
96 information(id: u64) -> Badge {
97 GET "{URL}/badges/{id}";
98 }
99
100 universe_badges(id: u64, sort_by: Option<BadgeSortBy>, paging: Paging<'_>) -> BadgesResponse {
101 GET "{URL}/universes/{id}/badges";
102 paging_query { paging, limit = 10 }
103 prelude {
104 let sort_by_lower = sort_by.as_ref().map(|s| s.to_string().to_lowercase());
105 }
106 query {
107 "sortBy" => sort_by_lower.as_deref().unwrap_or(""),
108 }
109 }
110
111 user_badges(id: u64, paging: Paging<'_>) -> BadgesResponse {
112 GET "{URL}/users/{id}/badges";
113 paging_query { paging, limit = 10 }
114 }
115
116 remove(id: u64, user_id: u64) -> () {
117 DELETE "{URL}/user/{user_id}/badges/{id}";
118 }
119
120 authenticated_remove(id: u64) -> () {
121 DELETE "{URL}/user/badges/{id}";
122 }
123}