algohub_server/routes/
contest.rs

1use rocket::{serde::json::Json, State};
2use surrealdb::{engine::remote::ws::Client, sql::Thing, Surreal};
3
4use crate::{
5    models::{
6        contest::{AddProblems, ContestProblem, CreateContest, UserContest},
7        error::Error,
8        response::{Empty, Response},
9        Credentials, OwnedId,
10    },
11    utils::{contest, session},
12    Result,
13};
14
15#[post("/create", data = "<contest>")]
16pub async fn create(db: &State<Surreal<Client>>, contest: Json<CreateContest>) -> Result<OwnedId> {
17    if !session::verify(db, &contest.auth.id, &contest.auth.token).await {
18        return Err(Error::Unauthorized(Json("Invalid credentials".into())));
19    }
20
21    let contest = contest.into_inner();
22    let contest = contest::create(db, &contest.auth.id, contest.data)
23        .await?
24        .ok_or(Error::ServerError(Json("Failed to create contest".into())))?;
25
26    Ok(Json(Response {
27        success: true,
28        message: "Contest created successfully".into(),
29        data: Some(OwnedId {
30            id: contest.id.unwrap().id.to_string(),
31        }),
32    }))
33}
34
35#[post("/problems/add", data = "<data>")]
36pub async fn add_problems(
37    db: &State<Surreal<Client>>,
38    data: Json<AddProblems<'_>>,
39) -> Result<Empty> {
40    if !session::verify(db, &data.auth.id, &data.auth.token).await {
41        return Err(Error::Unauthorized(Json("Invalid credentials".into())));
42    }
43
44    let problem = data.into_inner();
45    contest::add_problems(
46        db,
47        problem.contest_id.to_string(),
48        problem
49            .problem_ids
50            .iter()
51            .map(|&id| Thing::from(("problem", id)))
52            .collect(),
53    )
54    .await?;
55
56    Ok(Json(Response {
57        success: true,
58        message: "Problems added successfully".into(),
59        data: None,
60    }))
61}
62
63#[post("/list/all", data = "<auth>")]
64pub async fn list_all(
65    db: &State<Surreal<Client>>,
66    auth: Json<Credentials<'_>>,
67) -> Result<Vec<UserContest>> {
68    if !session::verify(db, auth.id, auth.token).await {
69        return Err(Error::Unauthorized(Json("Invalid credentials".into())));
70    }
71
72    let contests = contest::list_all(db).await?;
73    Ok(Json(Response {
74        success: true,
75        message: "Contests listed successfully".into(),
76        data: Some(contests.into_iter().map(|c| c.into()).collect()),
77    }))
78}
79
80#[post("/list/<id>/problems", data = "<auth>")]
81pub async fn list_problems(
82    db: &State<Surreal<Client>>,
83    id: &str,
84    auth: Json<Credentials<'_>>,
85) -> Result<Vec<ContestProblem>> {
86    if !session::verify(db, auth.id, auth.token).await {
87        return Err(Error::Unauthorized(Json("Invalid credentials".into())));
88    }
89
90    let problems = contest::list_problems(db, id, auth.id).await?;
91
92    Ok(Json(Response {
93        success: true,
94        message: "Problems listed successfully".into(),
95        data: Some(problems),
96    }))
97}
98
99#[post("/get/<id>", data = "<auth>")]
100pub async fn get(
101    db: &State<Surreal<Client>>,
102    id: &str,
103    auth: Json<Credentials<'_>>,
104) -> Result<UserContest> {
105    if !session::verify(db, auth.id, auth.token).await {
106        return Err(Error::Unauthorized(Json("Invalid credentials".into())));
107    }
108
109    let contest = contest::get(db, id)
110        .await?
111        .ok_or(Error::NotFound(Json("Contest not found".into())))?;
112
113    Ok(Json(Response {
114        success: true,
115        message: "Contest retrieved successfully".into(),
116        data: Some(contest.into()),
117    }))
118}
119
120pub fn routes() -> Vec<rocket::Route> {
121    use rocket::routes;
122    routes![create, get, add_problems, list_problems, list_all]
123}