animation type enum

This commit is contained in:
Brandon Thomas committed 2024-04-25 00:37:18 -04:00
1 parent 16a383d405
commit b462499f64
2 files changed
+143

No files matched your search

@@ -0,0 +1,142 @@
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
#[cfg(test)]
use strum::EnumCount;
#[cfg(test)]
use strum::EnumIter;
use utoipa::ToSchema;
/// Used in the `media_files` table in a `VARCHAR` field.
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[cfg_attr(test, derive(EnumIter, EnumCount))]
#[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum MediaFileAnimationType {
/// Animation or rig for MikuMikuDance (MMD).
MikuMikuDance,
/// Animation or rig for Mixamo
Mixamo,
/// Animation generated by MocapNet
MocapNet,
/// Animation or rig for Rigify.
Rigify,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
impl_enum_display_and_debug_using_to_str!(MediaFileAnimationType);
impl_mysql_enum_coders!(MediaFileAnimationType);
impl_mysql_from_row!(MediaFileAnimationType);
/// NB: Legacy API for older code.
impl MediaFileAnimationType {
pub fn to_str(&self) -> &'static str {
match self {
Self::MikuMikuDance => "miku_miku_dance",
Self::Mixamo => "mixamo",
Self::MocapNet => "mocap_net",
Self::Rigify => "rigify",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"miku_miku_dance" => Ok(Self::MikuMikuDance),
"mixamo" => Ok(Self::Mixamo),
"mocap_net" => Ok(Self::MocapNet),
"rigify" => Ok(Self::Rigify),
_ => 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::MikuMikuDance,
Self::Mixamo,
Self::MocapNet,
Self::Rigify,
])
}
}
#[cfg(test)]
mod tests {
use crate::by_table::media_files::media_file_animation_type::MediaFileAnimationType;
use crate::test_helpers::assert_serialization;
mod explicit_checks {
use super::*;
#[test]
fn test_serialization() {
assert_serialization(MediaFileAnimationType::MikuMikuDance, "miku_miku_dance");
assert_serialization(MediaFileAnimationType::Mixamo, "mixamo");
assert_serialization(MediaFileAnimationType::MocapNet, "mocap_net");
assert_serialization(MediaFileAnimationType::Rigify, "rigify");
}
#[test]
fn test_to_str() {
assert_eq!(MediaFileAnimationType::MikuMikuDance.to_str(), "miku_miku_dance");
assert_eq!(MediaFileAnimationType::Mixamo.to_str(), "mixamo");
assert_eq!(MediaFileAnimationType::MocapNet.to_str(), "mocap_net");
assert_eq!(MediaFileAnimationType::Rigify.to_str(), "rigify");
}
#[test]
fn test_from_str() {
assert_eq!(MediaFileAnimationType::from_str("miku_miku_dance").unwrap(), MediaFileAnimationType::MikuMikuDance);
assert_eq!(MediaFileAnimationType::from_str("mixamo").unwrap(), MediaFileAnimationType::Mixamo);
assert_eq!(MediaFileAnimationType::from_str("mocap_net").unwrap(), MediaFileAnimationType::MocapNet);
assert_eq!(MediaFileAnimationType::from_str("rigify").unwrap(), MediaFileAnimationType::Rigify);
assert!(MediaFileAnimationType::from_str("foo").is_err());
}
#[test]
fn all_variants() {
let mut variants = MediaFileAnimationType::all_variants();
assert_eq!(variants.len(), 4);
assert_eq!(variants.pop_first(), Some(MediaFileAnimationType::MikuMikuDance));
assert_eq!(variants.pop_first(), Some(MediaFileAnimationType::Mixamo));
assert_eq!(variants.pop_first(), Some(MediaFileAnimationType::MocapNet));
assert_eq!(variants.pop_first(), Some(MediaFileAnimationType::Rigify));
assert_eq!(variants.pop_first(), None);
}
}
mod mechanical_checks {
use super::*;
#[test]
fn variant_length() {
use strum::IntoEnumIterator;
assert_eq!(MediaFileAnimationType::all_variants().len(), MediaFileAnimationType::iter().len());
}
#[test]
fn round_trip() {
for variant in MediaFileAnimationType::all_variants() {
assert_eq!(variant, MediaFileAnimationType::from_str(variant.to_str()).unwrap());
assert_eq!(variant, MediaFileAnimationType::from_str(&format!("{}", variant)).unwrap());
assert_eq!(variant, MediaFileAnimationType::from_str(&format!("{:?}", variant)).unwrap());
}
}
#[test]
fn serialized_length_ok_for_database() {
const MAX_LENGTH : usize = 32;
for variant in MediaFileAnimationType::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_animation_type;
pub mod media_file_class;
pub mod media_file_origin_category;
pub mod media_file_origin_model_type;