mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 17:58:55 +00:00
MediaFileClass enum
This commit is contained in:
1 parent
1cb420f5a3
commit
ba0ad9a96f
2 files changed
+190
No files matched your search
@@ -0,0 +1,189 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Used in the `media_files` table in a `VARCHAR(16)` field.
|
||||
///
|
||||
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
|
||||
#[cfg_attr(test, derive(EnumIter, EnumCount))]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MediaFileClass {
|
||||
/// Unknown (default value)
|
||||
/// This will be present until we migrate all old files.
|
||||
Unknown,
|
||||
|
||||
/// Audio files: wav, mp3, etc.
|
||||
Audio,
|
||||
|
||||
/// Image files: png, jpeg, etc.
|
||||
Image,
|
||||
|
||||
/// Video files: mp4, etc.
|
||||
Video,
|
||||
|
||||
/// Engine "animations"
|
||||
Animation,
|
||||
|
||||
/// Engine "characters"
|
||||
Character,
|
||||
|
||||
/// Engine "prop" items
|
||||
Prop,
|
||||
|
||||
/// Engine scenes (internal and external scenes)
|
||||
Scene,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
impl_enum_display_and_debug_using_to_str!(MediaFileClass);
|
||||
impl_mysql_enum_coders!(MediaFileClass);
|
||||
impl_mysql_from_row!(MediaFileClass);
|
||||
|
||||
/// NB: Legacy API for older code.
|
||||
impl MediaFileClass {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Unknown => "unknown",
|
||||
Self::Audio => "audio",
|
||||
Self::Image => "image",
|
||||
Self::Video => "video",
|
||||
Self::Animation => "animation",
|
||||
Self::Character => "character",
|
||||
Self::Prop => "prop",
|
||||
Self::Scene => "scene",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"unknown" => Ok(Self::Unknown),
|
||||
"audio" => Ok(Self::Audio),
|
||||
"image" => Ok(Self::Image),
|
||||
"video" => Ok(Self::Video),
|
||||
"animation" => Ok(Self::Animation),
|
||||
"character" => Ok(Self::Character),
|
||||
"prop" => Ok(Self::Prop),
|
||||
"scene" => Ok(Self::Scene),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_variants() -> BTreeSet<Self> {
|
||||
// NB: BTreeSet is sorted
|
||||
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
|
||||
BTreeSet::from([
|
||||
Self::Unknown,
|
||||
Self::Audio,
|
||||
Self::Image,
|
||||
Self::Video,
|
||||
Self::Animation,
|
||||
Self::Character,
|
||||
Self::Prop,
|
||||
Self::Scene,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::by_table::media_files::media_file_class::MediaFileClass;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
mod serde {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
assert_serialization(MediaFileClass::Unknown, "unknown");
|
||||
assert_serialization(MediaFileClass::Audio, "audio");
|
||||
assert_serialization(MediaFileClass::Image, "image");
|
||||
assert_serialization(MediaFileClass::Video, "video");
|
||||
assert_serialization(MediaFileClass::Animation, "animation");
|
||||
assert_serialization(MediaFileClass::Character, "character");
|
||||
assert_serialization(MediaFileClass::Prop, "prop");
|
||||
assert_serialization(MediaFileClass::Scene, "scene");
|
||||
}
|
||||
}
|
||||
|
||||
mod impl_methods {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn to_str() {
|
||||
assert_eq!(MediaFileClass::Unknown.to_str(), "unknown");
|
||||
assert_eq!(MediaFileClass::Audio.to_str(), "audio");
|
||||
assert_eq!(MediaFileClass::Image.to_str(), "image");
|
||||
assert_eq!(MediaFileClass::Video.to_str(), "video");
|
||||
assert_eq!(MediaFileClass::Animation.to_str(), "animation");
|
||||
assert_eq!(MediaFileClass::Character.to_str(), "character");
|
||||
assert_eq!(MediaFileClass::Prop.to_str(), "prop");
|
||||
assert_eq!(MediaFileClass::Scene.to_str(), "scene");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(MediaFileClass::from_str("unknown").unwrap(), MediaFileClass::Unknown);
|
||||
assert_eq!(MediaFileClass::from_str("audio").unwrap(), MediaFileClass::Audio);
|
||||
assert_eq!(MediaFileClass::from_str("image").unwrap(), MediaFileClass::Image);
|
||||
assert_eq!(MediaFileClass::from_str("video").unwrap(), MediaFileClass::Video);
|
||||
assert_eq!(MediaFileClass::from_str("animation").unwrap(), MediaFileClass::Animation);
|
||||
assert_eq!(MediaFileClass::from_str("character").unwrap(), MediaFileClass::Character);
|
||||
assert_eq!(MediaFileClass::from_str("prop").unwrap(), MediaFileClass::Prop);
|
||||
assert_eq!(MediaFileClass::from_str("scene").unwrap(), MediaFileClass::Scene);
|
||||
assert!(MediaFileClass::from_str("foo").is_err());
|
||||
}
|
||||
}
|
||||
|
||||
mod manual_variant_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = MediaFileClass::all_variants();
|
||||
assert_eq!(variants.len(), 8);
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileClass::Unknown));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileClass::Audio));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileClass::Image));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileClass::Video));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileClass::Animation));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileClass::Character));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileClass::Prop));
|
||||
assert_eq!(variants.pop_first(), Some(MediaFileClass::Scene));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
mod mechanical_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn variant_length() {
|
||||
use strum::IntoEnumIterator;
|
||||
assert_eq!(MediaFileClass::all_variants().len(), MediaFileClass::iter().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip() {
|
||||
for variant in MediaFileClass::all_variants() {
|
||||
assert_eq!(variant, MediaFileClass::from_str(variant.to_str()).unwrap());
|
||||
assert_eq!(variant, MediaFileClass::from_str(&format!("{}", variant)).unwrap());
|
||||
assert_eq!(variant, MediaFileClass::from_str(&format!("{:?}", variant)).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialized_length_ok_for_database() {
|
||||
const MAX_LENGTH : usize = 16;
|
||||
for variant in MediaFileClass::all_variants() {
|
||||
let serialized = variant.to_str();
|
||||
assert!(serialized.len() > 0, "variant {:?} is too short", variant);
|
||||
assert!(serialized.len() <= MAX_LENGTH, "variant {:?} is too long", variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod media_file_class;
|
||||
pub mod media_file_origin_category;
|
||||
pub mod media_file_origin_model_type;
|
||||
pub mod media_file_origin_product_category;
|
||||
|
||||
Reference in new issue
Block a user