diff --git a/crates/_types/enums/src/lib.rs b/crates/_types/enums/src/lib.rs index 36761d942f..8b2a2e87d1 100644 --- a/crates/_types/enums/src/lib.rs +++ b/crates/_types/enums/src/lib.rs @@ -33,4 +33,5 @@ mod macros; pub mod by_table; pub mod common; +pub mod no_table; pub mod traits; diff --git a/crates/_types/enums/src/no_table/mod.rs b/crates/_types/enums/src/no_table/mod.rs new file mode 100644 index 0000000000..51ac556c25 --- /dev/null +++ b/crates/_types/enums/src/no_table/mod.rs @@ -0,0 +1 @@ +pub mod style_transfer; \ No newline at end of file diff --git a/crates/_types/enums/src/no_table/style_transfer/mod.rs b/crates/_types/enums/src/no_table/style_transfer/mod.rs new file mode 100644 index 0000000000..84c0a980bc --- /dev/null +++ b/crates/_types/enums/src/no_table/style_transfer/mod.rs @@ -0,0 +1 @@ +pub mod style_transfer_name; \ No newline at end of file diff --git a/crates/_types/enums/src/no_table/style_transfer/style_transfer_name.rs b/crates/_types/enums/src/no_table/style_transfer/style_transfer_name.rs new file mode 100644 index 0000000000..39d2044e7a --- /dev/null +++ b/crates/_types/enums/src/no_table/style_transfer/style_transfer_name.rs @@ -0,0 +1,134 @@ +use std::collections::BTreeSet; + +#[cfg(test)] +use strum::EnumCount; +#[cfg(test)] +use strum::EnumIter; +use utoipa::ToSchema; + +/// This enum is not backed by a particular database table. +/// It's used in APIs and Jobs to agree upon ComfyUI style transfer style configurations. +/// +/// 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 StyleTransferName { + #[serde(rename = "anime_2d")] + Anime2d, + #[serde(rename = "cartoon_3d")] + Cartoon3d, + Ink, + Origami, +} + +// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests! +impl_enum_display_and_debug_using_to_str!(StyleTransferName); +//impl_mysql_enum_coders!(StyleTransferName); +//impl_mysql_from_row!(StyleTransferName); + +/// NB: Legacy API for older code. +impl StyleTransferName { + pub fn to_str(&self) -> &'static str { + match self { + Self::Anime2d => "anime_2d", + Self::Cartoon3d => "cartoon_3d", + Self::Ink => "ink", + Self::Origami => "origami", + } + } + + pub fn from_str(value: &str) -> Result { + match value { + "anime_2d" => Ok(Self::Anime2d), + "cartoon_3d" => Ok(Self::Cartoon3d), + "ink" => Ok(Self::Ink), + "origami" => Ok(Self::Origami), + _ => Err(format!("invalid value: {:?}", value)), + } + } + + pub fn all_variants() -> BTreeSet { + // NB: BTreeSet is sorted + // NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc. + BTreeSet::from([ + Self::Anime2d, + Self::Cartoon3d, + Self::Ink, + Self::Origami, + ]) + } +} + +#[cfg(test)] +mod tests { + use crate::no_table::style_transfer::style_transfer_name::StyleTransferName; + use crate::test_helpers::assert_serialization; + + mod serde { + use super::*; + + #[test] + fn test_serialization() { + assert_serialization(StyleTransferName::Anime2d, "anime_2d"); + assert_serialization(StyleTransferName::Cartoon3d, "cartoon_3d"); + assert_serialization(StyleTransferName::Ink, "ink"); + assert_serialization(StyleTransferName::Origami, "origami"); + } + } + + mod impl_methods { + use super::*; + + #[test] + fn to_str() { + assert_eq!(StyleTransferName::Anime2d.to_str(), "anime_2d"); + assert_eq!(StyleTransferName::Cartoon3d.to_str(), "cartoon_3d"); + assert_eq!(StyleTransferName::Ink.to_str(), "ink"); + assert_eq!(StyleTransferName::Origami.to_str(), "origami"); + } + + #[test] + fn from_str() { + assert_eq!(StyleTransferName::from_str("anime_2d").unwrap(), StyleTransferName::Anime2d); + assert_eq!(StyleTransferName::from_str("cartoon_3d").unwrap(), StyleTransferName::Cartoon3d); + assert_eq!(StyleTransferName::from_str("ink").unwrap(), StyleTransferName::Ink); + assert_eq!(StyleTransferName::from_str("origami").unwrap(), StyleTransferName::Origami); + assert!(StyleTransferName::from_str("foo").is_err()); + } + } + + mod manual_variant_checks { + use super::*; + + #[test] + fn all_variants() { + let mut variants = StyleTransferName::all_variants(); + assert_eq!(variants.len(), 4); + assert_eq!(variants.pop_first(), Some(StyleTransferName::Anime2d)); + assert_eq!(variants.pop_first(), Some(StyleTransferName::Cartoon3d)); + assert_eq!(variants.pop_first(), Some(StyleTransferName::Ink)); + assert_eq!(variants.pop_first(), Some(StyleTransferName::Origami)); + assert_eq!(variants.pop_first(), None); + } + } + + mod mechanical_checks { + use super::*; + + #[test] + fn variant_length() { + use strum::IntoEnumIterator; + assert_eq!(StyleTransferName::all_variants().len(), StyleTransferName::iter().len()); + } + + #[test] + fn round_trip() { + for variant in StyleTransferName::all_variants() { + assert_eq!(variant, StyleTransferName::from_str(variant.to_str()).unwrap()); + assert_eq!(variant, StyleTransferName::from_str(&format!("{}", variant)).unwrap()); + assert_eq!(variant, StyleTransferName::from_str(&format!("{:?}", variant)).unwrap()); + } + } + } +} diff --git a/crates/_types/enums/src/test_helpers.rs b/crates/_types/enums/src/test_helpers.rs index 6d16bfddd5..c56cbf43dc 100644 --- a/crates/_types/enums/src/test_helpers.rs +++ b/crates/_types/enums/src/test_helpers.rs @@ -2,8 +2,14 @@ use serde::Serialize; -pub fn to_json(t: T) -> String { - toml::to_string(&t) +pub fn to_toml(t: &T) -> String { + toml::to_string(t) + .expect("serialization error") + .replace("\"", "") // JSON values are quoted, so we remove quotes +} + +pub fn to_json(t: &T) -> String { + serde_json::to_string(t) .expect("serialization error") .replace("\"", "") // JSON values are quoted, so we remove quotes } @@ -12,5 +18,6 @@ pub fn to_json(t: T) -> String { /// This is useful for ensuring stability of serialization. pub fn assert_serialization(t: T, expected: &str) { // TODO: See if there's a way to check the sqlx serialization - assert_eq!(&to_json(t), expected); + assert_eq!(&to_toml(&t), expected); + assert_eq!(&to_json(&t), expected); }