1use reqwest::{
2 Response,
3 header::{self, HeaderMap, HeaderValue},
4};
5
6use serde::de::DeserializeOwned;
7
8use crate::Error;
9
10#[derive(Default)]
11pub struct Cookie(String);
12
13impl std::fmt::Display for Cookie {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 write!(f, "{}", self.0)
16 }
17}
18
19impl From<&str> for Cookie {
20 fn from(value: &str) -> Self {
21 Self(format!(".ROBLOSECURITY={}", value))
22 }
23}
24
25#[derive(Default, Debug)]
26pub struct ClientRequestor {
27 pub(crate) client: reqwest::Client,
28 pub(crate) default_headers: HeaderMap,
29}
30
31#[derive(Default, Debug)]
32pub struct Client {
33 pub requestor: ClientRequestor,
34}
35
36impl Client {
37 pub fn from_cookie(cookie: Cookie) -> Self {
38 let client = reqwest::Client::new();
39 let mut default_headers = HeaderMap::new();
40
41 default_headers.insert(
42 header::USER_AGENT,
43 HeaderValue::from_str("Roblox/WinInet").unwrap(),
44 );
45
46 default_headers.insert(
47 header::COOKIE,
48 HeaderValue::from_str(&cookie.to_string()).unwrap(),
49 );
50
51 Client {
52 requestor: ClientRequestor {
53 client,
54 default_headers,
55 },
56 }
57 }
58}
59
60impl ClientRequestor {
61 pub(crate) async fn parse_json<T: DeserializeOwned>(
62 &self,
63 response: Response,
64 ) -> Result<T, Error> {
65 match response.json::<T>().await {
66 Ok(result) => Ok(result),
67 Err(_) => Err(Error::BadResponse),
68 }
69 }
70}