use std::borrow::Cow;
use topcoat_core::fnv1a::Fnv1a;
use crate::{ConstReader, ConstWriter};
#[derive(Debug, Clone, PartialEq)]
pub struct AssetOptions {
pub rename: Option<Cow<'static, str>>,
pub extension: Option<Cow<'static, str>>,
pub checksum: Option<Cow<'static, str>>,
pub content_type: Option<Cow<'static, str>>,
}
impl AssetOptions {
pub const NONE: Self = Self {
rename: None,
extension: None,
checksum: None,
content_type: None,
};
#[must_use]
pub fn rename(&self) -> Option<&str> {
self.rename.as_deref()
}
#[must_use]
pub fn extension(&self) -> Option<&str> {
self.extension.as_deref()
}
#[must_use]
pub fn checksum(&self) -> Option<&str> {
self.checksum.as_deref()
}
#[must_use]
pub fn content_type(&self) -> Option<&str> {
self.content_type.as_deref()
}
pub(crate) const fn encode_into(&self, w: &mut ConstWriter<'_>) {
w.write_str_opt(cow_as_str(self.rename.as_ref()));
w.write_str_opt(cow_as_str(self.extension.as_ref()));
w.write_str_opt(cow_as_str(self.checksum.as_ref()));
w.write_str_opt(cow_as_str(self.content_type.as_ref()));
}
pub(crate) const fn hash_into(&self, mut h: Fnv1a<u64>) -> Fnv1a<u64> {
h = hash_opt_str(h, cow_as_str(self.rename.as_ref()));
h = hash_opt_str(h, cow_as_str(self.extension.as_ref()));
h = hash_opt_str(h, cow_as_str(self.checksum.as_ref()));
h = hash_opt_str(h, cow_as_str(self.content_type.as_ref()));
h
}
pub(crate) fn decode_from(r: &mut ConstReader<'_>) -> Option<Self> {
Some(Self {
rename: r.read_str_opt()?.map(|s| Cow::Owned(s.to_owned())),
extension: r.read_str_opt()?.map(|s| Cow::Owned(s.to_owned())),
checksum: r.read_str_opt()?.map(|s| Cow::Owned(s.to_owned())),
content_type: r.read_str_opt()?.map(|s| Cow::Owned(s.to_owned())),
})
}
}
const fn cow_as_str<'a>(c: Option<&'a Cow<'static, str>>) -> Option<&'a str> {
match c {
None => None,
Some(Cow::Borrowed(s)) => Some(s),
Some(Cow::Owned(s)) => Some(s.as_str()),
}
}
const fn hash_opt_str(h: Fnv1a<u64>, s: Option<&str>) -> Fnv1a<u64> {
match s {
None => h.write(&[0]),
Some(s) => h.write(&[1]).write(s.as_bytes()),
}
}
#[macro_export]
macro_rules! asset_options {
($($field:ident $(: $expr:expr)?),* $(,)?) => {{
#[allow(clippy::needless_update)]
$crate::AssetOptions {
$($field: ::core::option::Option::Some(::std::borrow::Cow::Borrowed($($expr)?)),)*
..$crate::AssetOptions::NONE
}
}};
}