mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-12-22 19:31:35 +00:00
Enforce format on new details
This commit is contained in:
parent
f3c6239979
commit
521cdd5b9d
6 changed files with 67 additions and 59 deletions
|
@ -22,8 +22,7 @@ pub(crate) struct Details {
|
||||||
frames: Option<u32>,
|
frames: Option<u32>,
|
||||||
content_type: Serde<mime::Mime>,
|
content_type: Serde<mime::Mime>,
|
||||||
created_at: MaybeHumanDate,
|
created_at: MaybeHumanDate,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
format: InternalFormat,
|
||||||
format: Option<InternalFormat>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Details {
|
impl Details {
|
||||||
|
@ -57,12 +56,8 @@ impl Details {
|
||||||
Ok(Details::from_parts(format, width, height, frames))
|
Ok(Details::from_parts(format, width, height, frames))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn internal_format(&self) -> Option<InternalFormat> {
|
pub(crate) fn internal_format(&self) -> InternalFormat {
|
||||||
if let Some(format) = self.format {
|
self.format
|
||||||
return Some(format);
|
|
||||||
}
|
|
||||||
|
|
||||||
InternalFormat::maybe_from_media_type(&self.content_type, self.frames.is_some())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn media_type(&self) -> mime::Mime {
|
pub(crate) fn media_type(&self) -> mime::Mime {
|
||||||
|
@ -74,15 +69,27 @@ impl Details {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn video_format(&self) -> Option<InternalVideoFormat> {
|
pub(crate) fn video_format(&self) -> Option<InternalVideoFormat> {
|
||||||
if *self.content_type == crate::formats::mimes::video_mp4() {
|
match self.format {
|
||||||
return Some(InternalVideoFormat::Mp4);
|
InternalFormat::Video(format) => Some(format),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if *self.content_type == crate::formats::mimes::video_webm() {
|
pub(crate) fn from_parts_full(
|
||||||
return Some(InternalVideoFormat::Webm);
|
format: InternalFormat,
|
||||||
|
width: u16,
|
||||||
|
height: u16,
|
||||||
|
frames: Option<u32>,
|
||||||
|
created_at: MaybeHumanDate,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
frames,
|
||||||
|
content_type: Serde::new(format.media_type()),
|
||||||
|
created_at,
|
||||||
|
format,
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_parts(
|
pub(crate) fn from_parts(
|
||||||
|
@ -97,7 +104,7 @@ impl Details {
|
||||||
frames,
|
frames,
|
||||||
content_type: Serde::new(format.media_type()),
|
content_type: Serde::new(format.media_type()),
|
||||||
created_at: MaybeHumanDate::HumanDate(OffsetDateTime::now_utc()),
|
created_at: MaybeHumanDate::HumanDate(OffsetDateTime::now_utc()),
|
||||||
format: Some(format),
|
format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,8 +130,8 @@ async fn process<S: Store + 'static>(
|
||||||
|
|
||||||
let input_format = input_details
|
let input_format = input_details
|
||||||
.internal_format()
|
.internal_format()
|
||||||
.and_then(|format| format.processable_format())
|
.processable_format()
|
||||||
.expect("Valid details should always have internal format");
|
.expect("Already verified format is processable");
|
||||||
|
|
||||||
let Some(format) = input_format.process_to(output_format) else {
|
let Some(format) = input_format.process_to(output_format) else {
|
||||||
return Err(UploadError::InvalidProcessExtension.into());
|
return Err(UploadError::InvalidProcessExtension.into());
|
||||||
|
|
24
src/lib.rs
24
src/lib.rs
|
@ -102,13 +102,7 @@ async fn ensure_details<S: Store + 'static>(
|
||||||
return Err(UploadError::MissingAlias.into());
|
return Err(UploadError::MissingAlias.into());
|
||||||
};
|
};
|
||||||
|
|
||||||
let details = repo.details(&identifier).await?.and_then(|details| {
|
let details = repo.details(&identifier).await?;
|
||||||
if details.internal_format().is_some() {
|
|
||||||
Some(details)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(details) = details {
|
if let Some(details) = details {
|
||||||
tracing::debug!("details exist");
|
tracing::debug!("details exist");
|
||||||
|
@ -784,13 +778,7 @@ async fn process<S: Store + 'static>(
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
if let Some(identifier) = identifier_opt {
|
if let Some(identifier) = identifier_opt {
|
||||||
let details = repo.details(&identifier).await?.and_then(|details| {
|
let details = repo.details(&identifier).await?;
|
||||||
if details.internal_format().is_some() {
|
|
||||||
Some(details)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let details = if let Some(details) = details {
|
let details = if let Some(details) = details {
|
||||||
tracing::debug!("details exist");
|
tracing::debug!("details exist");
|
||||||
|
@ -916,13 +904,7 @@ async fn process_head<S: Store + 'static>(
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
if let Some(identifier) = identifier_opt {
|
if let Some(identifier) = identifier_opt {
|
||||||
let details = repo.details(&identifier).await?.and_then(|details| {
|
let details = repo.details(&identifier).await?;
|
||||||
if details.internal_format().is_some() {
|
|
||||||
Some(details)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let details = if let Some(details) = details {
|
let details = if let Some(details) = details {
|
||||||
tracing::debug!("details exist");
|
tracing::debug!("details exist");
|
||||||
|
|
|
@ -398,14 +398,7 @@ where
|
||||||
.details(identifier)
|
.details(identifier)
|
||||||
.await
|
.await
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err(MigrateError::Details)?
|
.map_err(MigrateError::Details)?;
|
||||||
.and_then(|details| {
|
|
||||||
if details.internal_format().is_some() {
|
|
||||||
Some(details)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let details = if let Some(details) = details_opt {
|
let details = if let Some(details) = details_opt {
|
||||||
details
|
details
|
||||||
|
|
|
@ -151,11 +151,7 @@ async fn do_migrate_hash_04<S: Store>(
|
||||||
|
|
||||||
let hash = old_hash[..].try_into().expect("Invalid hash size");
|
let hash = old_hash[..].try_into().expect("Invalid hash size");
|
||||||
|
|
||||||
let hash = Hash::new(
|
let hash = Hash::new(hash, size, hash_details.internal_format());
|
||||||
hash,
|
|
||||||
size,
|
|
||||||
hash_details.internal_format().expect("format exists"),
|
|
||||||
);
|
|
||||||
|
|
||||||
let _ = HashRepo::create(new_repo.as_ref(), hash.clone(), &identifier).await?;
|
let _ = HashRepo::create(new_repo.as_ref(), hash.clone(), &identifier).await?;
|
||||||
|
|
||||||
|
@ -212,13 +208,7 @@ async fn fetch_or_generate_details<S: Store>(
|
||||||
config: &Configuration,
|
config: &Configuration,
|
||||||
identifier: &S::Identifier,
|
identifier: &S::Identifier,
|
||||||
) -> Result<Details, Error> {
|
) -> Result<Details, Error> {
|
||||||
let details_opt = old_repo.details(identifier).await?.and_then(|details| {
|
let details_opt = old_repo.details(identifier).await?;
|
||||||
if details.internal_format().is_some() {
|
|
||||||
Some(details)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(details) = details_opt {
|
if let Some(details) = details_opt {
|
||||||
Ok(details)
|
Ok(details)
|
||||||
|
|
|
@ -57,6 +57,41 @@ pub(crate) struct SledRepo {
|
||||||
_db: Db,
|
_db: Db,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub(crate) struct OldDetails {
|
||||||
|
width: u16,
|
||||||
|
height: u16,
|
||||||
|
frames: Option<u32>,
|
||||||
|
content_type: crate::serde_str::Serde<mime::Mime>,
|
||||||
|
created_at: crate::details::MaybeHumanDate,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
format: Option<crate::formats::InternalFormat>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OldDetails {
|
||||||
|
fn into_details(self) -> Option<Details> {
|
||||||
|
let OldDetails {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
frames,
|
||||||
|
content_type,
|
||||||
|
created_at,
|
||||||
|
format,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
let format = format.or_else(|| {
|
||||||
|
crate::formats::InternalFormat::maybe_from_media_type(
|
||||||
|
&content_type,
|
||||||
|
self.frames.is_some(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Some(Details::from_parts_full(
|
||||||
|
format, width, height, frames, created_at,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SledRepo {
|
impl SledRepo {
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub(crate) fn build(path: PathBuf, cache_capacity: u64) -> color_eyre::Result<Option<Self>> {
|
pub(crate) fn build(path: PathBuf, cache_capacity: u64) -> color_eyre::Result<Option<Self>> {
|
||||||
|
@ -135,11 +170,12 @@ impl IdentifierRepo for SledRepo {
|
||||||
|
|
||||||
let opt = b!(self.identifier_details, identifier_details.get(key));
|
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::<OldDetails>(&ivec))
|
||||||
.transpose()
|
.transpose()
|
||||||
.map_err(SledError::from)
|
.map_err(SledError::from)
|
||||||
.map_err(RepoError::from)
|
.map_err(RepoError::from)
|
||||||
.map_err(StoreError::from)
|
.map_err(StoreError::from)
|
||||||
|
.map(|opt| opt.and_then(OldDetails::into_details))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue