ord 0.4.2

◉ Ordinal wallet and block explorer
Documentation
use super::*;

#[derive(Debug, PartialEq, Copy, Clone)]
pub(crate) enum Media {
  Audio,
  Iframe,
  Image,
  Pdf,
  Text,
  Unknown,
  Video,
}

impl Media {
  pub(crate) fn content_type_for_extension(extension: &str) -> Result<&'static str, Error> {
    let extension = extension.to_lowercase();

    for (content_type, _, extensions) in TABLE {
      if extensions.contains(&extension.as_str()) {
        return Ok(content_type);
      }
    }

    let mut extensions = TABLE
      .iter()
      .map(|(_, _, extensions)| extensions[0])
      .collect::<Vec<&str>>();

    extensions.sort();

    Err(anyhow!(
      "unsupported file extension `.{extension}`, supported extensions: {}",
      extensions.join(" "),
    ))
  }
}

impl FromStr for Media {
  type Err = Error;

  fn from_str(s: &str) -> Result<Self, Self::Err> {
    for entry in TABLE {
      if entry.0 == s {
        return Ok(entry.1);
      }
    }

    Err(anyhow!("unknown content type: {s}"))
  }
}

const TABLE: &[(&str, Media, &[&str])] = &[
  ("application/pdf", Media::Pdf, &["pdf"]),
  ("audio/flac", Media::Audio, &["flac"]),
  ("audio/mpeg", Media::Audio, &["mp3"]),
  ("audio/wav", Media::Audio, &["wav"]),
  ("image/apng", Media::Image, &["apng"]),
  ("image/gif", Media::Image, &["gif"]),
  ("image/jpeg", Media::Image, &["jpg", "jpeg"]),
  ("image/png", Media::Image, &["png"]),
  ("image/svg+xml", Media::Iframe, &["svg"]),
  ("image/webp", Media::Image, &["webp"]),
  ("text/html;charset=utf-8", Media::Iframe, &["html"]),
  ("text/plain;charset=utf-8", Media::Text, &["txt"]),
  ("video/webm", Media::Video, &["webm"]),
];

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn for_extension() {
    assert_eq!(
      Media::content_type_for_extension("jpg").unwrap(),
      "image/jpeg"
    );
    assert_eq!(
      Media::content_type_for_extension("jpeg").unwrap(),
      "image/jpeg"
    );
    assert_eq!(
      Media::content_type_for_extension("JPG").unwrap(),
      "image/jpeg"
    );

    assert_regex_match!(
      Media::content_type_for_extension("foo").unwrap_err(),
      r"unsupported file extension `\.foo`, supported extensions: apng .*"
    );
  }
}