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 ToString for DateTime {
40 fn to_string(&self) -> String {
41 self.0.clone()
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 ChallengeRequired(Challenge),
69 ChallengeFailed,
70 InvalidChallengeId,
71 InvalidTwoStepVerificationCode,
72 TwoStepVerificationMaintenance,
73 Multiple(Vec<ApiError>),
74 PermissionError,
75}
76
77#[repr(u8)]
78#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq)]
79pub enum AssetTypeId {
80 Image = 1,
81 TShirt,
82 Audio,
83 Mesh,
84 Lua,
85 Hat = 8,
86 Place,
87 Model,
88 Shirt,
89 Pants,
90 Decal,
91 Head = 17,
92 Face,
93 Gear,
94 Badge = 21,
95 Animation = 24,
96 Torso = 27,
97 RightArm,
98 LeftArm,
99 LeftLeg,
100 RightLeg,
101 Package,
102 Gamepass = 34,
103 Plugin = 38,
104 MeshPart = 40,
105 HairAccessory,
106 FaceAccessory,
107 NeckAccessory,
108 ShoulderAccessory,
109 FrontAccessory,
110 BackAccessory,
111 WaistAccessory,
112 ClimbAnimation,
113 DeathAnimation,
114 FallAnimation,
115 IdleAnimation,
116 JumpAnimation,
117 RunAnimation,
118 SwimAnimation,
119 WalkAnimation,
120 PoseAnimation,
121 EarAccessory,
122 EyeAccessory,
123 EmoteAnimation = 61,
124 Video,
125 TShirtAccessory = 64,
126 ShirtAccessory,
127 PantsAccessory,
128 JacketAccessory,
129 SweaterAccessory,
130 ShortsAccessory,
131 LeftShoeAccessory,
132 RightShoeAccessory,
133 DressSkirtAccessory,
134 FontFamily,
135 EyebrowAccessory = 76,
136 EyelashAccessory,
137 MoodAnimation,
138 DynamicHead,
139}
140
141#[derive(Clone, Copy, Debug, PartialEq, Eq)]
142pub struct Paging<'a> {
143 pub cursor: Option<&'a str>,
144 pub limit: Option<u16>,
145 pub order: Option<SortOrder>,
146}
147
148#[derive(Clone, Copy, Debug, Default, Serialize, PartialEq, Eq)]
149pub enum SortOrder {
150 #[default]
151 #[serde(rename = "Asc")]
152 Ascending,
153 #[serde(rename = "Desc")]
154 Descending,
155}
156
157impl ToString for SortOrder {
158 fn to_string(&self) -> String {
159 match self {
160 SortOrder::Ascending => "Asc".to_string(),
161 SortOrder::Descending => "Desc".to_string(),
162 }
163 }
164}
165
166impl Default for Paging<'_> {
167 fn default() -> Self {
168 Self {
169 cursor: None,
170 limit: Some(10),
171 order: Some(SortOrder::Ascending),
172 }
173 }
174}
175
176impl<'a> Paging<'a> {
177 pub fn new(
178 cursor: Option<&'a str>,
179 limit: Option<u16>,
180 order: Option<SortOrder>,
181 ) -> Paging<'a> {
182 Self {
183 cursor,
184 limit,
185 order,
186 }
187 }
188}