use crate::errors::Result;
use mime;
use strum::EnumProperty;
#[derive(EnumProperty, EnumString, Display, Debug, Hash, PartialEq)]
pub enum MediaTypes {
#[strum(serialize = "application/vnd.docker.distribution.manifest.v1+json")]
#[strum(props(Sub = "vnd.docker.distribution.manifest.v1+json"))]
ManifestV2S1,
#[strum(
serialize = "application/vnd.docker.distribution.manifest.v1+prettyjws",
// TODO: find a generic way to handle this form
serialize = "application/vnd.docker.distribution.manifest.v1+prettyjws; charset=utf-8",
)]
#[strum(props(Sub = "vnd.docker.distribution.manifest.v1+prettyjws"))]
ManifestV2S1Signed,
#[strum(serialize = "application/vnd.docker.distribution.manifest.v2+json")]
#[strum(props(Sub = "vnd.docker.distribution.manifest.v2+json"))]
ManifestV2S2,
#[strum(serialize = "application/vnd.docker.distribution.manifest.list.v2+json")]
#[strum(props(Sub = "vnd.docker.distribution.manifest.list.v2+json"))]
ManifestList,
#[strum(serialize = "application/vnd.docker.image.rootfs.diff.tar.gzip")]
#[strum(props(Sub = "vnd.docker.image.rootfs.diff.tar.gzip"))]
ImageLayerTgz,
#[strum(serialize = "application/vnd.docker.container.image.v1+json")]
#[strum(props(Sub = "vnd.docker.container.image.v1+json"))]
ContainerConfigV1,
#[strum(serialize = "application/json")]
#[strum(props(Sub = "json"))]
ApplicationJson,
}
impl MediaTypes {
pub fn from_mime(mtype: &mime::Mime) -> Result<Self> {
match (mtype.type_(), mtype.subtype(), mtype.suffix()) {
(mime::APPLICATION, mime::JSON, _) => Ok(MediaTypes::ApplicationJson),
(mime::APPLICATION, subt, Some(suff)) => {
match (subt.to_string().as_str(), suff.to_string().as_str()) {
("vnd.docker.distribution.manifest.v1", "json") => Ok(MediaTypes::ManifestV2S1),
("vnd.docker.distribution.manifest.v1", "prettyjws") => {
Ok(MediaTypes::ManifestV2S1Signed)
}
("vnd.docker.distribution.manifest.v2", "json") => Ok(MediaTypes::ManifestV2S2),
("vnd.docker.distribution.manifest.list.v2", "json") => {
Ok(MediaTypes::ManifestList)
}
("vnd.docker.image.rootfs.diff.tar.gzip", _) => Ok(MediaTypes::ImageLayerTgz),
("vnd.docker.container.image.v1", "json") => Ok(MediaTypes::ContainerConfigV1),
_ => Err(crate::Error::UnknownMimeType(mtype.clone())),
}
}
_ => Err(crate::Error::UnknownMimeType(mtype.clone())),
}
}
pub fn to_mime(&self) -> mime::Mime {
match self {
&MediaTypes::ApplicationJson => Ok(mime::APPLICATION_JSON),
m => {
if let Some(s) = m.get_str("Sub") {
("application/".to_string() + s).parse()
} else {
"application/star".parse()
}
}
}
.expect("to_mime should be always successful")
}
}