Enforce format on new details

This commit is contained in:
asonix 2023-08-16 12:36:18 -05:00
parent f3c6239979
commit 521cdd5b9d
6 changed files with 67 additions and 59 deletions

View File

@ -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,
} }
} }
} }

View File

@ -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());

View File

@ -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");

View File

@ -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

View File

@ -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)

View File

@ -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))
} }
} }