1pub mod api;
2pub mod challenge;
3pub mod client;
4pub mod validation;
5
6use challenge::Challenge;
7use chrono::{Datelike, TimeZone, Utc};
8use serde::{Deserialize, Serialize};
9
10#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
12pub struct DateTime(String);
13impl DateTime {
14 pub fn from_ymd(year: i32, month: u8, day: u8) -> Self {
15 Self(
16 Utc.with_ymd_and_hms(year, month as u32, day as u32, 0, 0, 0)
17 .unwrap()
18 .to_rfc3339(),
19 )
20 }
21
22 pub fn day(&self) -> u8 {
23 chrono::DateTime::parse_from_rfc3339(&self.0).unwrap().day() as u8
24 }
25
26 pub fn month(&self) -> u8 {
27 chrono::DateTime::parse_from_rfc3339(&self.0)
28 .unwrap()
29 .month() as u8
30 }
31
32 pub fn year(&self) -> i32 {
33 chrono::DateTime::parse_from_rfc3339(&self.0)
34 .unwrap()
35 .year()
36 }
37}
38
39impl std::fmt::Display for DateTime {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 write!(f, "{}", self.0)
42 }
43}
44
45#[derive(Debug)]
46pub enum Error {
47 ApiError(ApiError),
48 BadResponse,
49 ReqwestError(reqwest::Error),
50 IoError(std::io::Error),
51}
52
53#[derive(Clone, Debug, PartialEq, Eq)]
54pub enum ApiError {
55 Internal,
56 BadRequest,
57 RequestMissingArgument(String),
58 Ratelimited,
59 Unknown(u16),
60 Unauthorized,
61 InvalidBirthdate,
62 InvalidDisplayName,
63 InvalidGender,
64 UserNotFound,
65 InvalidUserId,
66 PinIsLocked,
67 TokenValidation,
68 CaptchaFailed,
69 ChallengeRequired(Challenge),
70 ChallengeFailed,
71 InvalidChallengeId,
72 InvalidTwoStepVerificationCode,
73 TwoStepVerificationMaintenance,
74 Multiple(Vec<ApiError>),
75 PermissionError,
76 AccontLocked,
77 AccountIssue,
78 InvalidCredentials,
79 UnverifiedCredentials,
80 ExistingLoginSession,
81 DefaultLoginRequired,
82 VNGAppLoginRequired,
83 LuoBuAppLoginRequired,
84 SocialNetworkLoginRequired,
85 InvalidAssetId,
86}
87
88#[repr(u8)]
89#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq)]
90pub enum AssetTypeId {
91 Image = 1,
92 TShirt,
93 Audio,
94 Mesh,
95 Lua,
96 Hat = 8,
97 Place,
98 Model,
99 Shirt,
100 Pants,
101 Decal,
102 Head = 17,
103 Face,
104 Gear,
105 Badge = 21,
106 Animation = 24,
107 Torso = 27,
108 RightArm,
109 LeftArm,
110 LeftLeg,
111 RightLeg,
112 Package,
113 Gamepass = 34,
114 Plugin = 38,
115 MeshPart = 40,
116 HairAccessory,
117 FaceAccessory,
118 NeckAccessory,
119 ShoulderAccessory,
120 FrontAccessory,
121 BackAccessory,
122 WaistAccessory,
123 ClimbAnimation,
124 DeathAnimation,
125 FallAnimation,
126 IdleAnimation,
127 JumpAnimation,
128 RunAnimation,
129 SwimAnimation,
130 WalkAnimation,
131 PoseAnimation,
132 EarAccessory,
133 EyeAccessory,
134 EmoteAnimation = 61,
135 Video,
136 TShirtAccessory = 64,
137 ShirtAccessory,
138 PantsAccessory,
139 JacketAccessory,
140 SweaterAccessory,
141 ShortsAccessory,
142 LeftShoeAccessory,
143 RightShoeAccessory,
144 DressSkirtAccessory,
145 FontFamily,
146 EyebrowAccessory = 76,
147 EyelashAccessory,
148 MoodAnimation,
149 DynamicHead,
150}
151
152#[repr(u8)]
153#[derive(Clone, Debug, Default, Serialize, PartialEq, Eq)]
154pub enum Currency {
155 #[default]
156 Robux = 1,
157 Tickets,
158}
159
160#[derive(Clone, Copy, Debug, PartialEq, Eq)]
161pub struct Paging<'a> {
162 pub cursor: Option<&'a str>,
163 pub limit: Option<u16>,
164 pub order: Option<SortOrder>,
165}
166
167#[derive(Clone, Copy, Debug, Default, Serialize, PartialEq, Eq)]
168pub enum SortOrder {
169 #[default]
170 #[serde(rename = "Asc")]
171 Ascending,
172 #[serde(rename = "Desc")]
173 Descending,
174}
175
176impl std::fmt::Display for SortOrder {
177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178 write!(
179 f,
180 "{}",
181 match self {
182 SortOrder::Ascending => "Asc",
183 SortOrder::Descending => "Desc",
184 }
185 )
186 }
187}
188
189impl Default for Paging<'_> {
190 fn default() -> Self {
191 Self {
192 cursor: None,
193 limit: Some(10),
194 order: Some(SortOrder::Ascending),
195 }
196 }
197}
198
199impl<'a> Paging<'a> {
200 pub fn new(
201 cursor: Option<&'a str>,
202 limit: Option<u16>,
203 order: Option<SortOrder>,
204 ) -> Paging<'a> {
205 Self {
206 cursor,
207 limit,
208 order,
209 }
210 }
211}