Now let's take a silly one
1

Configure Feed

Select the types of activity you want to include in your feed.

at main 2.9 kB View raw
1use std::fmt; 2 3use axum::http::StatusCode; 4use axum::response::{IntoResponse, Response}; 5 6#[derive(Debug, Clone, Copy, PartialEq, Eq)] 7pub enum PackLimit { 8 Objects, 9 ObjectBytes, 10 TotalBytes, 11 DeltaDepth, 12} 13 14impl fmt::Display for PackLimit { 15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 16 f.write_str(match self { 17 PackLimit::Objects => "object count", 18 PackLimit::ObjectBytes => "per-object size", 19 PackLimit::TotalBytes => "total decompressed size", 20 PackLimit::DeltaDepth => "delta chain depth", 21 }) 22 } 23} 24 25#[derive(Debug, thiserror::Error)] 26pub enum PackError { 27 #[error("repository not found")] 28 NotFound, 29 #[error("repository index is warming, retry shortly")] 30 Unavailable, 31 #[error("invalid request path: {0}")] 32 BadPath(String), 33 #[error("unsupported service")] 34 UnsupportedService, 35 #[error("push is served over SSH, not HTTP")] 36 PushOverSsh, 37 #[error("protocol: {0}")] 38 Protocol(String), 39 #[error("unsupported request content-encoding: {0}")] 40 UnsupportedEncoding(String), 41 #[error("pkt-line: {0}")] 42 PktLine(#[from] std::io::Error), 43 #[error("pack: {0}")] 44 Pack(String), 45 #[error("pack exceeds {0} limit")] 46 LimitExceeded(PackLimit), 47 #[error("upload-pack selection exceeded its object-set cap")] 48 SelectionTooLarge, 49 #[error("upload-pack selection exceeded its time budget")] 50 SelectionTimeout, 51 #[error(transparent)] 52 Git(knot_git::GitError), 53} 54 55impl From<knot_git::GitError> for PackError { 56 fn from(error: knot_git::GitError) -> Self { 57 use knot_git::SelectionLimit; 58 match error { 59 knot_git::GitError::Selection(SelectionLimit::Objects) => PackError::SelectionTooLarge, 60 knot_git::GitError::Selection(SelectionLimit::Time) => PackError::SelectionTimeout, 61 other => PackError::Git(other), 62 } 63 } 64} 65 66impl IntoResponse for PackError { 67 fn into_response(self) -> Response { 68 let status = match self { 69 PackError::NotFound => StatusCode::NOT_FOUND, 70 PackError::Unavailable => StatusCode::SERVICE_UNAVAILABLE, 71 PackError::PushOverSsh => StatusCode::FORBIDDEN, 72 PackError::BadPath(_) | PackError::UnsupportedService => StatusCode::BAD_REQUEST, 73 PackError::Protocol(_) | PackError::PktLine(_) => StatusCode::BAD_REQUEST, 74 PackError::UnsupportedEncoding(_) => StatusCode::UNSUPPORTED_MEDIA_TYPE, 75 PackError::LimitExceeded(_) => StatusCode::PAYLOAD_TOO_LARGE, 76 PackError::SelectionTooLarge | PackError::SelectionTimeout => { 77 StatusCode::SERVICE_UNAVAILABLE 78 } 79 PackError::Pack(_) | PackError::Git(_) => StatusCode::INTERNAL_SERVER_ERROR, 80 }; 81 (status, self.to_string()).into_response() 82 } 83}