Skip to content

Commit

Permalink
feat: struct change of kebab-case and feat for all activities with …
Browse files Browse the repository at this point in the history
…query
  • Loading branch information
7086cmd committed Apr 27, 2024
1 parent a494ca7 commit 1ecdd00
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 76 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ reqwest = "0.12.3"
rsa = "0.9.6"
serde = "1.0.198"
serde_json = "1.0.116"
serde_qs = { version = "0.13.0", features = ["axum"] }
tokio = { version = "1.37.0", features = ["full"] }
uuid = "1.8.0"

Expand Down
11 changes: 0 additions & 11 deletions src/database.rs

This file was deleted.

14 changes: 14 additions & 0 deletions src/database/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// src/database.rs

use crate::config;
use mongodb::{options::ClientOptions, Client, Database};
use std::error::Error;

pub async fn create_client() -> Result<Database, Box<dyn Error>> {
println!("Connecting to MongoDB");
let mut client_options = ClientOptions::parse(config::MONGO_URL).await?;
client_options.app_name = Some("zvms".to_string());
let client = Client::with_options(client_options)?;
let database = client.database("zvms");
Ok(database)
}
10 changes: 6 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
mod config;
mod database;
mod models;
mod utils;
mod routers;
mod utils;
use axum::{routing::get, Extension, Router};
use std::sync::Arc;
use tokio::sync::Mutex;
Expand All @@ -12,12 +12,14 @@ async fn main() {
let client = database::create_client()
.await
.expect("Failed to create client");
let shared_client = Arc::new(Mutex::new(client));

println!("Server running on port 3000");
let shared_client = Arc::new(Mutex::new(client));

// Set up the router
let app = Router::new().route("/activity/", get(routers::activities::read::read_one)).layer(Extension(shared_client));
let app = Router::new()
.route("/activity/:id", get(routers::activities::read::read_one))
.route("/activity/", get(routers::activities::read::read_all))
.layer(Extension(shared_client.clone()));

// Run the server
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
Expand Down
9 changes: 7 additions & 2 deletions src/models/activities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use bson::oid::ObjectId;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ActivityType {
Specified,
Social,
Expand All @@ -21,6 +22,7 @@ impl ToString for ActivityType {
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ActivityStatus {
Effective,
Pending,
Expand All @@ -38,6 +40,7 @@ impl ToString for ActivityStatus {
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ActivityMemberStatus {
Effective,
Pending,
Expand All @@ -59,6 +62,7 @@ impl ToString for ActivityMemberStatus {
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ActivityMode {
OnCampus,
OffCampus,
Expand Down Expand Up @@ -98,11 +102,12 @@ pub struct ActivityMemberHistory {

#[derive(Debug, Serialize, Deserialize)]
pub struct Activity {
#[serde(rename = "_id")]
pub _id: ObjectId,
pub name: String,
pub description: String,
#[serde(rename = "type")]
pub activity_type: ActivityType,
pub name: String,
pub description: String,
pub duration: i32,
pub date: String,
pub created_at: String,
Expand Down
26 changes: 2 additions & 24 deletions src/models/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use bson::oid::ObjectId;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum GroupPermission {
Student,
Secretary,
Expand All @@ -12,37 +13,14 @@ pub enum GroupPermission {
System,
}

impl ToString for GroupPermission {
fn to_string(&self) -> String {
match *self {
GroupPermission::Student => "student".to_string(),
GroupPermission::Secretary => "secretary".to_string(),
GroupPermission::Department => "department".to_string(),
GroupPermission::Auditor => "auditor".to_string(),
GroupPermission::Inspector => "inspector".to_string(),
GroupPermission::Admin => "admin".to_string(),
GroupPermission::System => "system".to_string(),
}
}
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum GroupType {
Class,
Permission,
Group,
}

impl ToString for GroupType {
fn to_string(&self) -> String {
match *self {
GroupType::Class => "class".to_string(),
GroupType::Permission => "permission".to_string(),
GroupType::Group => "group".to_string(),
}
}
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Group {
pub _id: ObjectId,
Expand Down
14 changes: 3 additions & 11 deletions src/models/response.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ResponseStatus {
Success,
Error,
}

impl ToString for ResponseStatus {
fn to_string(&self) -> String {
match self {
ResponseStatus::Success => "success".to_string(),
ResponseStatus::Error => "error".to_string(),
}
}
}

#[derive(Debug, Serialize, Deserialize)]
pub struct SuccessResponse<T, M> {
pub status: ResponseStatus,
pub code: i32,
pub data: Vec<T>,
pub data: T,
pub metadata: Option<M>,
}

Expand All @@ -37,7 +29,7 @@ pub enum Response<T, M> {
}

impl<T, M> Response<T, M> {
pub fn success(data: Vec<T>, metadata: Option<M>) -> Self {
pub fn success(data: T, metadata: Option<M>) -> Self {
Response::Success(SuccessResponse {
status: ResponseStatus::Success,
code: 200,
Expand Down
13 changes: 2 additions & 11 deletions src/models/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,17 @@ use bson::oid::ObjectId;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum UserSex {
Male,
Female,
Unknown,
}

impl ToString for UserSex {
fn to_string(&self) -> String {
match *self {
UserSex::Male => "male".to_string(),
UserSex::Female => "female".to_string(),
UserSex::Unknown => "unknown".to_string(),
}
}
}

#[derive(Debug, Serialize, Deserialize)]
pub struct User {
pub _id: ObjectId,
pub id: u64,
pub id: String,
pub name: String,
pub group: Vec<String>,
password: String,
Expand Down
70 changes: 57 additions & 13 deletions src/routers/activities/read.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::models::{
activities::Activity,
users::User,
response::{ErrorResponse, Response as ZVMSResponse, ResponseStatus, SuccessResponse},
};
use axum::{
extract::Extension,
extract::{Extension, Path, Query},
http::StatusCode,
response::{IntoResponse, Json},
};
Expand Down Expand Up @@ -50,12 +51,19 @@ pub async fn read_all(Extension(db): Extension<Arc<Mutex<Database>>>) -> impl In
}
}

pub struct ReadActivityQuery {
page: Option<u32>,
perpage: Option<u32>,
query: Option<String>,
}

pub async fn read_with_filter(
Extension(db): Extension<Arc<Mutex<Database>>>,
page: u32,
perpage: u32,
query: String,
Query(ReadActivityQuery { page, perpage, query }): Query<ReadActivityQuery>,
) -> Json<Vec<Activity>> {
let page = page.unwrap_or(1);
let perpage = perpage.unwrap_or(10);
let query = query.unwrap_or("".to_string());
let db = db.lock().await;
let collection = db.collection("activities") as Collection<Activity>;
let pipeline = vec![
Expand Down Expand Up @@ -84,18 +92,54 @@ pub async fn read_with_filter(
}

pub async fn read_one(
Extension(db): Extension<Arc<Mutex<Database>>>,
id: String,
) -> Result<Json<Activity>, String> {
let db = db.lock().await;
Extension(client): Extension<Arc<Mutex<Database>>>,
Path(id): Path<String>,
) -> impl IntoResponse {
println!("ID: {:?}", id);
let db = client.lock().await;
let collection = db.collection("activities");
let filter = doc! {"_id": ObjectId::parse_str(&id).unwrap()};
let result = collection.find_one(filter, None).await.unwrap();
let id = ObjectId::parse_str(&id);
if let Err(_) = id {
let response = ErrorResponse {
status: ResponseStatus::Error,
code: 400,
message: "Invalid ID".to_string(),
};
let response = serde_json::to_string(&response).unwrap();
return (StatusCode::BAD_REQUEST, Json(response));
}
let id = id.unwrap();
let filter = doc! {"_id": id};
let result = collection.find_one(filter, None).await;
if let Err(e) = result {
let response = ErrorResponse {
status: ResponseStatus::Error,
code: 500,
message: "Failed to read activity: ".to_string() + &e.to_string(),
};
let response = serde_json::to_string(&response).unwrap();
return (StatusCode::INTERNAL_SERVER_ERROR, Json(response));
}
let result: Option<Activity> = result.unwrap();
match result {
Some(document) => {
let activity = from_document(document).unwrap();
Ok(Json(activity))
let response: SuccessResponse<Activity, ()> = SuccessResponse {
status: ResponseStatus::Success,
code: 200,
data: document,
metadata: None,
};
let response = serde_json::to_string(&response).unwrap();
(StatusCode::OK, Json(response))
}
None => {
let response = ErrorResponse {
status: ResponseStatus::Error,
code: 404,
message: "Activity not found".to_string(),
};
let response = serde_json::to_string(&response).unwrap();
(StatusCode::NOT_FOUND, Json(response))
}
None => Err("Activity not found".into()),
}
}

0 comments on commit 1ecdd00

Please sign in to comment.