feat: allow any target request

This commit is contained in:
daimond113 2024-08-14 20:55:10 +02:00
parent 7aaea85a2d
commit 07ee4b9617
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C

View file

@ -1,21 +1,24 @@
use crate::{ use std::collections::BTreeSet;
error::Error,
package::{s3_name, PackageResponse, S3_SIGN_DURATION},
AppState,
};
use actix_web::{ use actix_web::{
http::header::{ACCEPT, LOCATION}, http::header::{ACCEPT, LOCATION},
web, HttpRequest, HttpResponse, Responder, web, HttpRequest, HttpResponse, Responder,
}; };
use rusty_s3::{actions::GetObject, S3Action};
use semver::Version;
use serde::{Deserialize, Deserializer};
use pesde::{ use pesde::{
manifest::target::TargetKind, manifest::target::TargetKind,
names::PackageName, names::PackageName,
source::{git_index::GitBasedSource, pesde::IndexFile}, source::{git_index::GitBasedSource, pesde::IndexFile},
}; };
use rusty_s3::{actions::GetObject, S3Action};
use semver::Version; use crate::{
use serde::{Deserialize, Deserializer}; error::Error,
use std::collections::BTreeSet; package::{s3_name, PackageResponse, S3_SIGN_DURATION},
AppState,
};
#[derive(Debug)] #[derive(Debug)]
pub enum VersionRequest { pub enum VersionRequest {
@ -33,16 +36,38 @@ impl<'de> Deserialize<'de> for VersionRequest {
return Ok(VersionRequest::Latest); return Ok(VersionRequest::Latest);
} }
Version::parse(&s) s.parse()
.map(VersionRequest::Specific) .map(VersionRequest::Specific)
.map_err(serde::de::Error::custom) .map_err(serde::de::Error::custom)
} }
} }
#[derive(Debug)]
pub enum TargetRequest {
Any,
Specific(TargetKind),
}
impl<'de> Deserialize<'de> for TargetRequest {
fn deserialize<D>(deserializer: D) -> Result<TargetRequest, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
if s.eq_ignore_ascii_case("any") {
return Ok(TargetRequest::Any);
}
s.parse()
.map(TargetRequest::Specific)
.map_err(serde::de::Error::custom)
}
}
pub async fn get_package_version( pub async fn get_package_version(
request: HttpRequest, request: HttpRequest,
app_state: web::Data<AppState>, app_state: web::Data<AppState>,
path: web::Path<(PackageName, VersionRequest, TargetKind)>, path: web::Path<(PackageName, VersionRequest, TargetRequest)>,
) -> Result<impl Responder, Error> { ) -> Result<impl Responder, Error> {
let (name, version, target) = path.into_inner(); let (name, version, target) = path.into_inner();
@ -57,16 +82,26 @@ pub async fn get_package_version(
} }
}; };
let mut versions = entries let Some((v_id, entry)) = ({
.into_iter() let version = match version {
.filter(|(v_id, _)| *v_id.target() == target); VersionRequest::Latest => match entries.keys().map(|k| k.version()).max() {
Some(latest) => latest.clone(),
None => return Ok(HttpResponse::NotFound().finish()),
},
VersionRequest::Specific(version) => version,
};
let version = match version { let mut versions = entries
VersionRequest::Latest => versions.max_by_key(|(v, _)| v.version().clone()), .into_iter()
VersionRequest::Specific(version) => versions.find(|(v, _)| *v.version() == version), .filter(|(v_id, _)| *v_id.version() == version);
};
let Some((v_id, entry)) = version else { match target {
TargetRequest::Any => versions.min_by_key(|(v_id, _)| *v_id.target()),
TargetRequest::Specific(kind) => {
versions.find(|(_, entry)| entry.target.kind() == kind)
}
}
}) else {
return Ok(HttpResponse::NotFound().finish()); return Ok(HttpResponse::NotFound().finish());
}; };