leetcode_core/
lib.rs

1pub mod errors;
2pub mod graphql;
3pub mod types;
4use errors::AppResult;
5pub use graphql::client::GQLLeetcodeRequest;
6pub use graphql::query::problemset_question_list::Query as QuestionRequest;
7pub use graphql::query::question_content::Query as QuestionContentRequest;
8pub use graphql::query::run_code::RunCodeRequest;
9pub use graphql::query::submit_code::SubmitCodeRequest;
10pub use graphql::query::EditorDataRequest;
11use reqwest::header::{HeaderMap, HeaderValue};
12use reqwest::Client;
13use std::sync::OnceLock;
14pub use types::editor_data::QuestionData as EditorDataResponse;
15pub use types::problemset_question_list::Root as QuestionResponse;
16
17pub static REQ_CLIENT: OnceLock<reqwest::Client> = OnceLock::new();
18
19pub async fn init(csrf: &str, sess: &str) -> AppResult<()> {
20    let client = build_reqwest_client(csrf, sess).await?;
21    REQ_CLIENT.get_or_init(|| client);
22    Ok(())
23}
24
25pub(crate) fn get_client() -> &'static Client {
26    REQ_CLIENT.get().expect("Client not initialized")
27}
28
29pub async fn build_reqwest_client(csrf: &str, sess: &str) -> AppResult<Client> {
30    let mut headers = HeaderMap::new();
31    let header_k_v = [
32        (
33            "Cookie",
34            format!("LEETCODE_SESSION={sess}; csrftoken={csrf}"),
35        ),
36        ("Content-Type", "application/json".to_string()),
37        ("x-csrftoken", csrf.to_string()),
38        ("Origin", "https://leetcode.com".to_string()),
39        ("Referer", "https://leetcode.com".to_string()),
40        ("Connection", "keep-alive".to_string()),
41    ];
42
43    for (key, value) in header_k_v {
44        headers.append(key, HeaderValue::from_str(value.as_str())?);
45    }
46
47    let client = reqwest::ClientBuilder::new()
48        .default_headers(headers)
49        .build()?;
50    Ok(client)
51}