Fetch latest pushed version for crate search results
Diff
chartered-db/src/crates.rs | 16 ++++++++++++++++
chartered-frontend/src/pages/Search.tsx | 3 ++-
chartered-web/src/endpoints/web_api/crates/search.rs | 53 ++++++++++++++++++++++++++++++++++++++---------------
3 files changed, 50 insertions(+), 22 deletions(-)
@@ -282,6 +282,22 @@
}
impl CrateWithPermissions {
pub async fn latest_version(
self: Arc<Self>,
conn: ConnectionPool,
) -> Result<Option<CrateVersion<'static>>> {
tokio::task::spawn_blocking(move || {
let conn = conn.get()?;
Ok(CrateVersion::belonging_to(&self.crate_)
.order_by(crate_versions::id.desc())
.limit(1)
.get_result::<CrateVersion>(&conn)
.optional()?)
})
.await?
}
pub async fn version(
self: Arc<Self>,
conn: ConnectionPool,
@@ -110,6 +110,7 @@
description: string;
homepage?: string;
repository?: string;
version: string;
}
function CrateResults({
@@ -170,7 +171,7 @@
/{crate.name}
</h4>
</Link>
<h6 className="text-secondary m-0 mt-1">0.1.2</h6>
<h6 className="text-secondary m-0 mt-1">{crate.version}</h6>
</div>
<p className="m-0">{crate.description}</p>
@@ -1,6 +1,5 @@
use axum::{extract, Json};
use chartered_db::{crates::Crate, permissions::UserPermission, users::User, ConnectionPool};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use thiserror::Error;
@@ -23,7 +22,6 @@
version: String,
homepage: Option<String>,
repository: Option<String>,
updated: DateTime<Utc>,
permissions: UserPermission,
}
@@ -32,25 +30,38 @@
extract::Extension(user): extract::Extension<Arc<User>>,
extract::Query(req): extract::Query<RequestParams>,
) -> Result<Json<Response>, Error> {
let crates = Crate::search(db, user.id, req.q, 5)
.await?
.into_iter()
.map(|(org, crates_with_permissions)| {
crates_with_permissions
.into_iter()
.map(move |v| ResponseCrate {
organisation: org.name.to_string(),
name: v.crate_.name,
description: v.crate_.description,
version: "test".to_string(),
homepage: v.crate_.homepage,
repository: v.crate_.repository,
updated: Utc::now(),
permissions: v.permissions,
})
})
.flatten()
.collect();
let crates = futures::future::try_join_all(
Crate::search(db.clone(), user.id, req.q, 5)
.await?
.into_iter()
.map(move |(org, crates_with_permissions)| {
let db = db.clone();
crates_with_permissions
.into_iter()
.map(Arc::new)
.map(move |v| {
let db = db.clone();
let org_name = org.name.clone();
async move {
let version = v.clone().latest_version(db).await?;
Ok::<_, Error>(ResponseCrate {
organisation: org_name,
name: v.crate_.name.clone(),
description: v.crate_.description.clone(),
version: version.map(|v| v.version).unwrap_or_default(),
homepage: v.crate_.homepage.clone(),
repository: v.crate_.repository.clone(),
permissions: v.permissions.clone(),
})
}
})
})
.flatten(),
)
.await?;
Ok(Json(Response { crates }))
}