From 8fb90a6f69b6984e1b6c19a5a31f7a21d655c2bf Mon Sep 17 00:00:00 2001 From: asonix Date: Thu, 31 Aug 2023 16:26:45 -0500 Subject: [PATCH] Give a meaningful distinction for format in details --- src/details.rs | 93 +++++++++++++++++++++++++++++++++++++----------- src/lib.rs | 18 +++++----- src/repo/sled.rs | 4 +-- 3 files changed, 85 insertions(+), 30 deletions(-) diff --git a/src/details.rs b/src/details.rs index f494a22..edf921b 100644 --- a/src/details.rs +++ b/src/details.rs @@ -17,8 +17,30 @@ pub(crate) struct HumanDate { pub(crate) timestamp: time::OffsetDateTime, } -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[derive(Debug, serde::Serialize)] +enum ApiFormat { + Image, + Animation, + Video, +} + +#[derive(Debug, serde::Serialize)] +pub(crate) struct ApiDetails { + width: u16, + height: u16, + frames: Option, + content_type: Serde, + created_at: HumanDate, + format: ApiFormat, +} + +#[derive(Clone, Debug)] pub(crate) struct Details { + pub(crate) inner: DetailsInner, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +pub(crate) struct DetailsInner { width: u16, height: u16, frames: Option, @@ -28,12 +50,39 @@ pub(crate) struct Details { } impl Details { + pub(crate) fn into_api_details(self) -> ApiDetails { + let Details { + inner: + DetailsInner { + width, + height, + frames, + content_type, + created_at, + format, + }, + } = self; + + ApiDetails { + width, + height, + frames, + content_type, + created_at, + format: match format { + InternalFormat::Image(_) => ApiFormat::Image, + InternalFormat::Animation(_) => ApiFormat::Animation, + InternalFormat::Video(_) => ApiFormat::Video, + }, + } + } + pub(crate) fn is_video(&self) -> bool { - self.content_type.type_() == "video" + self.inner.content_type.type_() == "video" } pub(crate) fn created_at(&self) -> time::OffsetDateTime { - self.created_at.timestamp + self.inner.created_at.timestamp } pub(crate) async fn from_bytes(timeout: u64, input: web::Bytes) -> Result { @@ -74,19 +123,19 @@ impl Details { } pub(crate) fn internal_format(&self) -> InternalFormat { - self.format + self.inner.format } pub(crate) fn media_type(&self) -> mime::Mime { - (*self.content_type).clone() + (*self.inner.content_type).clone() } pub(crate) fn system_time(&self) -> std::time::SystemTime { - self.created_at.into() + self.inner.created_at.into() } pub(crate) fn video_format(&self) -> Option { - match self.format { + match self.inner.format { InternalFormat::Video(format) => Some(format), _ => None, } @@ -100,12 +149,14 @@ impl Details { created_at: HumanDate, ) -> Self { Self { - width, - height, - frames, - content_type: Serde::new(format.media_type()), - created_at, - format, + inner: DetailsInner { + width, + height, + frames, + content_type: Serde::new(format.media_type()), + created_at, + format, + }, } } @@ -116,14 +167,16 @@ impl Details { frames: Option, ) -> Self { Self { - width, - height, - frames, - content_type: Serde::new(format.media_type()), - created_at: HumanDate { - timestamp: OffsetDateTime::now_utc(), + inner: DetailsInner { + width, + height, + frames, + content_type: Serde::new(format.media_type()), + created_at: HumanDate { + timestamp: OffsetDateTime::now_utc(), + }, + format, }, - format, } } } diff --git a/src/lib.rs b/src/lib.rs index 1454e42..6ccb89e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,7 +34,7 @@ use actix_web::{ http::header::{CacheControl, CacheDirective, LastModified, Range, ACCEPT_RANGES}, web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer, }; -use details::HumanDate; +use details::{ApiDetails, HumanDate}; use futures_core::Stream; use metrics_exporter_prometheus::PrometheusBuilder; use middleware::Metrics; @@ -296,7 +296,7 @@ async fn handle_upload( files.push(serde_json::json!({ "file": alias.to_string(), "delete_token": delete_token.to_string(), - "details": details, + "details": details.into_api_details(), })); } } @@ -446,7 +446,7 @@ async fn claim_upload( "files": [{ "file": alias.to_string(), "delete_token": token.to_string(), - "details": details, + "details": details.into_api_details(), }] }))) } @@ -543,7 +543,7 @@ async fn do_download_inline( "files": [{ "file": alias.to_string(), "delete_token": delete_token.to_string(), - "details": details, + "details": details.into_api_details(), }] }))) } @@ -603,7 +603,7 @@ struct PageJson { struct HashJson { hex: String, aliases: Vec, - details: Option
, + details: Option, } /// Get a page of hashes @@ -637,7 +637,9 @@ async fn page( let identifier = repo.identifier(hash.clone()).await?; let details = if let Some(identifier) = identifier { - repo.details(&identifier).await? + repo.details(&identifier) + .await? + .map(|d| d.into_api_details()) } else { None }; @@ -769,7 +771,7 @@ async fn process_details( let details = details.ok_or(UploadError::NoFiles)?; - Ok(HttpResponse::Ok().json(&details)) + Ok(HttpResponse::Ok().json(&details.into_api_details())) } async fn not_found_hash(repo: &ArcRepo) -> Result, Error> { @@ -1105,7 +1107,7 @@ async fn do_details( ) -> Result { let details = ensure_details(&repo, &store, &config, &alias).await?; - Ok(HttpResponse::Ok().json(&details)) + Ok(HttpResponse::Ok().json(&details.into_api_details())) } /// Serve files based on alias query diff --git a/src/repo/sled.rs b/src/repo/sled.rs index bad6006..ec4f63b 100644 --- a/src/repo/sled.rs +++ b/src/repo/sled.rs @@ -932,7 +932,7 @@ impl DetailsRepo for SledRepo { details: &Details, ) -> Result<(), StoreError> { let key = identifier.to_bytes()?; - let details = serde_json::to_vec(&details) + let details = serde_json::to_vec(&details.inner) .map_err(SledError::from) .map_err(RepoError::from)?; @@ -950,7 +950,7 @@ impl DetailsRepo for SledRepo { let opt = b!(self.identifier_details, identifier_details.get(key)); - opt.map(|ivec| serde_json::from_slice(&ivec)) + opt.map(|ivec| serde_json::from_slice(&ivec).map(|inner| Details { inner })) .transpose() .map_err(SledError::from) .map_err(RepoError::from)