mirror of
https://git.asonix.dog/asonix/pict-rs.git
synced 2024-11-25 02:51:17 +00:00
Give a meaningful distinction for format in details
This commit is contained in:
parent
dce0827099
commit
8fb90a6f69
3 changed files with 85 additions and 30 deletions
|
@ -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<u32>,
|
||||
content_type: Serde<mime::Mime>,
|
||||
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<u32>,
|
||||
|
@ -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<Self, Error> {
|
||||
|
@ -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<InternalVideoFormat> {
|
||||
match self.format {
|
||||
match self.inner.format {
|
||||
InternalFormat::Video(format) => Some(format),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -100,12 +149,14 @@ impl Details {
|
|||
created_at: HumanDate,
|
||||
) -> Self {
|
||||
Self {
|
||||
inner: DetailsInner {
|
||||
width,
|
||||
height,
|
||||
frames,
|
||||
content_type: Serde::new(format.media_type()),
|
||||
created_at,
|
||||
format,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,6 +167,7 @@ impl Details {
|
|||
frames: Option<u32>,
|
||||
) -> Self {
|
||||
Self {
|
||||
inner: DetailsInner {
|
||||
width,
|
||||
height,
|
||||
frames,
|
||||
|
@ -124,6 +176,7 @@ impl Details {
|
|||
timestamp: OffsetDateTime::now_utc(),
|
||||
},
|
||||
format,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
18
src/lib.rs
18
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<S: Store + 'static>(
|
|||
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<S: Store + 'static>(
|
|||
"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<S: Store + 'static>(
|
|||
"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<String>,
|
||||
details: Option<Details>,
|
||||
details: Option<ApiDetails>,
|
||||
}
|
||||
|
||||
/// 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<S: Store>(
|
|||
|
||||
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<Option<(Alias, Hash)>, Error> {
|
||||
|
@ -1105,7 +1107,7 @@ async fn do_details<S: Store + 'static>(
|
|||
) -> Result<HttpResponse, Error> {
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue