roblox_api/
lib.rs

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// TODO: using this wrapper as I couldn't figure out how to use chronos datetime alone
11#[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}