Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 56 additions & 66 deletions src/controllers/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ use super::helpers::pagination::*;
use crate::app::AppState;
use crate::models::Category;
use crate::schema::categories;
use crate::tasks::spawn_blocking;
use crate::util::errors::AppResult;
use crate::util::RequestUtils;
use crate::views::{EncodableCategory, EncodableCategoryWithSubcategories};
use axum::extract::Path;
use axum::Json;
use diesel::prelude::*;
use diesel_async::async_connection_wrapper::AsyncConnectionWrapper;
use diesel::QueryDsl;
use diesel_async::RunQueryDsl;
use http::request::Parts;
use serde_json::Value;

Expand All @@ -20,86 +19,77 @@ pub async fn index(app: AppState, req: Parts) -> AppResult<Json<Value>> {
// to paginate this.
let options = PaginationOptions::builder().gather(&req)?;

let conn = app.db_read().await?;
spawn_blocking(move || {
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
let mut conn = app.db_read().await?;

let query = req.query();
let sort = query.get("sort").map_or("alpha", String::as_str);
let query = req.query();
let sort = query.get("sort").map_or("alpha", String::as_str);

let offset = options.offset().unwrap_or_default();
let offset = options.offset().unwrap_or_default();

let categories = Category::toplevel(conn, sort, options.per_page, offset)?;
let categories = categories
.into_iter()
.map(Category::into)
.collect::<Vec<EncodableCategory>>();
let categories = Category::toplevel(&mut conn, sort, options.per_page, offset).await?;
let categories = categories
.into_iter()
.map(Category::into)
.collect::<Vec<EncodableCategory>>();

// Query for the total count of categories
let total = Category::count_toplevel(conn)?;
// Query for the total count of categories
let total = Category::count_toplevel(&mut conn).await?;

Ok(Json(json!({
"categories": categories,
"meta": { "total": total },
})))
})
.await
Ok(Json(json!({
"categories": categories,
"meta": { "total": total },
})))
}

/// Handles the `GET /categories/:category_id` route.
pub async fn show(state: AppState, Path(slug): Path<String>) -> AppResult<Json<Value>> {
let conn = state.db_read().await?;
spawn_blocking(move || {
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
let mut conn = state.db_read().await?;

let cat: Category = Category::by_slug(&slug).first(conn)?;
let subcats = cat
.subcategories(conn)?
.into_iter()
.map(Category::into)
.collect();
let parents = cat
.parent_categories(conn)?
.into_iter()
.map(Category::into)
.collect();
let cat: Category = Category::by_slug(&slug).first(&mut conn).await?;
let subcats = cat
.subcategories(&mut conn)
.await?
.into_iter()
.map(Category::into)
.collect();
let parents = cat
.parent_categories(&mut conn)
.await?
.into_iter()
.map(Category::into)
.collect();

let cat = EncodableCategory::from(cat);
let cat_with_subcats = EncodableCategoryWithSubcategories {
id: cat.id,
category: cat.category,
slug: cat.slug,
description: cat.description,
created_at: cat.created_at,
crates_cnt: cat.crates_cnt,
subcategories: subcats,
parent_categories: parents,
};
let cat = EncodableCategory::from(cat);
let cat_with_subcats = EncodableCategoryWithSubcategories {
id: cat.id,
category: cat.category,
slug: cat.slug,
description: cat.description,
created_at: cat.created_at,
crates_cnt: cat.crates_cnt,
subcategories: subcats,
parent_categories: parents,
};

Ok(Json(json!({ "category": cat_with_subcats })))
})
.await
Ok(Json(json!({ "category": cat_with_subcats })))
}

/// Handles the `GET /category_slugs` route.
pub async fn slugs(state: AppState) -> AppResult<Json<Value>> {
let conn = state.db_read().await?;
spawn_blocking(move || {
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
let mut conn = state.db_read().await?;

let slugs: Vec<Slug> = categories::table
.select((categories::slug, categories::slug, categories::description))
.order(categories::slug)
.load(conn)?;
let slugs: Vec<Slug> = categories::table
.select((categories::slug, categories::slug, categories::description))
.order(categories::slug)
.load(&mut conn)
.await?;

#[derive(Serialize, Queryable)]
struct Slug {
id: String,
slug: String,
description: String,
}
#[derive(Serialize, Queryable)]
struct Slug {
id: String,
slug: String,
description: String,
}

Ok(Json(json!({ "category_slugs": slugs })))
})
.await
Ok(Json(json!({ "category_slugs": slugs })))
}
14 changes: 8 additions & 6 deletions src/controllers/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ use serde_json::Value;

/// Handles the `GET /summary` route.
pub async fn summary(state: AppState) -> AppResult<Json<Value>> {
let conn = state.db_read().await?;
let mut conn = state.db_read().await?;

let popular_categories = Category::toplevel(&mut conn, "crates", 10, 0)
.await?
.into_iter()
.map(Category::into)
.collect::<Vec<EncodableCategory>>();

spawn_blocking(move || {
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();

Expand Down Expand Up @@ -116,11 +123,6 @@ pub async fn summary(state: AppState) -> AppResult<Json<Value>> {
.map(Keyword::into)
.collect::<Vec<EncodableKeyword>>();

let popular_categories = Category::toplevel(conn, "crates", 10, 0)?
.into_iter()
.map(Category::into)
.collect::<Vec<EncodableCategory>>();

Ok(Json(json!({
"num_downloads": num_downloads,
"num_crates": num_crates,
Expand Down
Loading