algohub_server/routes/
solution.rs

1use crate::{
2    models::{
3        error::Error,
4        response::{Empty, Response},
5        solution::{CreateSolution, ListSolutions, Solution, UserSolution},
6        Credentials, OwnedId,
7    },
8    utils::{session, solution},
9    Result,
10};
11use rocket::{post, serde::json::Json, State};
12use surrealdb::{engine::remote::ws::Client, Surreal};
13
14#[post("/create", data = "<sol>")]
15pub async fn create(db: &State<Surreal<Client>>, sol: Json<CreateSolution<'_>>) -> Result<OwnedId> {
16    if !session::verify(db, sol.id, sol.token).await {
17        return Err(Error::Unauthorized(Json(
18            "Failed to grant permission".into(),
19        )));
20    }
21
22    let solution = solution::create(db, sol.into_inner())
23        .await?
24        .ok_or(Error::ServerError(Json("Failed to create solution".into())))?;
25
26    Ok(Json(Response {
27        success: true,
28        message: "Solution created successfully".to_string(),
29        data: Some(OwnedId {
30            id: solution.id.unwrap().id.to_string(),
31        }),
32    }))
33}
34
35#[post("/get/<id>", data = "<auth>")]
36pub async fn get(
37    db: &State<Surreal<Client>>,
38    id: &str,
39    auth: Json<Option<Credentials<'_>>>,
40) -> Result<UserSolution> {
41    let solution = solution::get::<Solution>(db, id)
42        .await?
43        .ok_or(Error::NotFound(Json(
44            "Solution with specified id not found".into(),
45        )))?;
46
47    let authed_id = if let Some(auth) = auth.into_inner() {
48        if !session::verify(db, auth.id, auth.token).await {
49            return Err(Error::Unauthorized(Json("Invalid credentials".into())));
50        } else {
51            Some(auth.id)
52        }
53    } else {
54        None
55    };
56
57    if authed_id.is_none() {
58        return Err(Error::Unauthorized(Json(
59            "You have no permission to access this solution".into(),
60        )));
61    }
62
63    Ok(Json(Response {
64        success: true,
65        message: "Solution found".to_string(),
66        data: Some(solution.into()),
67    }))
68}
69
70#[post("/update/<id>", data = "<sol>")]
71pub async fn update(
72    db: &State<Surreal<Client>>,
73    id: &str,
74    sol: Json<CreateSolution<'_>>,
75) -> Result<Empty> {
76    if !session::verify(db, sol.id, sol.token).await {
77        return Err(Error::Unauthorized(Json("Invalid credentials".into())));
78    }
79
80    solution::update(db, id, sol.into_inner())
81        .await?
82        .ok_or(Error::ServerError(Json(
83            "Failed to update solution, please try again later.".into(),
84        )))?;
85
86    Ok(Json(Response {
87        success: true,
88        message: "Solution updated successful".to_string(),
89        data: None,
90    }))
91}
92
93#[post("/list", data = "<data>")]
94pub async fn list(db: &State<Surreal<Client>>, data: Json<ListSolutions>) -> Result<Vec<Solution>> {
95    let result = solution::list(
96        db,
97        ("problem".to_string(), data.into_inner().problem).into(),
98    )
99    .await?;
100
101    if result.is_empty() {
102        return Err(Error::NotFound(Json("Solution not found".into())));
103    }
104
105    Ok(Json(Response {
106        success: true,
107        message: "Solution found successfully".to_string(),
108        data: Some(result),
109    }))
110}
111
112#[post("/delete/<id>", data = "<sol>")]
113pub async fn delete(
114    db: &State<Surreal<Client>>,
115    id: &str,
116    sol: Json<Credentials<'_>>,
117) -> Result<Empty> {
118    if !session::verify(db, sol.id, sol.token).await {
119        return Err(Error::Unauthorized(Json(
120            "Failed to grant permission".into(),
121        )));
122    }
123
124    solution::delete(db, id).await?;
125
126    Ok(Response {
127        success: true,
128        message: "Solution deleted successfully".to_string(),
129        data: None,
130    }
131    .into())
132}
133
134pub fn routes() -> Vec<rocket::Route> {
135    use rocket::routes;
136    routes![create, get, update, list, delete]
137}