mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 09:28:11 +00:00
Prompts enums
This commit is contained in:
1 parent
48a6b1a046
commit
b4a9da50de
5 files changed
+179
-2
No files matched your search
@@ -19,9 +19,9 @@ CREATE TABLE prompts (
|
||||
-- Original product to which the prompt applied.
|
||||
-- Prompts may or may not be compatible across products.
|
||||
-- Possible values:
|
||||
-- * 'artcraft_app'
|
||||
-- * 'stable_diffusion' (legacy)
|
||||
-- * 'comfy_ui' (legacy)
|
||||
-- * 'artcraft_app'
|
||||
prompt_type VARCHAR(16) NOT NULL,
|
||||
|
||||
-- What type of model was used to generate the result.
|
||||
|
||||
@@ -13,6 +13,7 @@ pub mod media_files;
|
||||
pub mod media_uploads;
|
||||
pub mod model_categories;
|
||||
pub mod model_weights;
|
||||
pub mod prompt_context_items;
|
||||
pub mod prompts;
|
||||
pub mod tag_uses;
|
||||
pub mod trending_model_analytics;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pub mod prompt_context_semantic_type;
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Used in the `prompt_context_items` 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, Deserialize, Serialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PromptContextSemanticType {
|
||||
/// Image-to-Video starting frame
|
||||
VidStartFrame,
|
||||
|
||||
/// Image-to-Video ending frame
|
||||
VidEndFrame,
|
||||
|
||||
/// Standard image reference without a semantic type (e.g. Sora/ChatGPT 4o/gpt-image-1)
|
||||
Imgref,
|
||||
|
||||
ImgrefCharacter,
|
||||
ImgrefStyle,
|
||||
ImgrefBg,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
impl_enum_display_and_debug_using_to_str!(PromptContextSemanticType);
|
||||
impl_mysql_enum_coders!(PromptContextSemanticType);
|
||||
impl_mysql_from_row!(PromptContextSemanticType);
|
||||
|
||||
/// NB: Legacy API for older code.
|
||||
impl PromptContextSemanticType {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::VidStartFrame => "vid_start_frame",
|
||||
Self::VidEndFrame => "vid_end_frame",
|
||||
Self::Imgref => "imgref",
|
||||
Self::ImgrefCharacter => "imgref_character",
|
||||
Self::ImgrefStyle => "imgref_style",
|
||||
Self::ImgrefBg => "imgref_bg",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"vid_start_frame" => Ok(Self::VidStartFrame),
|
||||
"vid_end_frame" => Ok(Self::VidEndFrame),
|
||||
"imgref" => Ok(Self::Imgref),
|
||||
"imgref_character" => Ok(Self::ImgrefCharacter),
|
||||
"imgref_style" => Ok(Self::ImgrefStyle),
|
||||
"imgref_bg" => Ok(Self::ImgrefBg),
|
||||
_ => 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::VidStartFrame,
|
||||
Self::VidEndFrame,
|
||||
Self::Imgref,
|
||||
Self::ImgrefCharacter,
|
||||
Self::ImgrefStyle,
|
||||
Self::ImgrefBg,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::by_table::prompt_context_items::prompt_context_semantic_type::PromptContextSemanticType;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
mod serde {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
assert_serialization(PromptContextSemanticType::VidStartFrame, "vid_start_frame");
|
||||
assert_serialization(PromptContextSemanticType::VidEndFrame, "vid_end_frame");
|
||||
assert_serialization(PromptContextSemanticType::Imgref, "imgref");
|
||||
assert_serialization(PromptContextSemanticType::ImgrefCharacter, "imgref_character");
|
||||
assert_serialization(PromptContextSemanticType::ImgrefStyle, "imgref_style");
|
||||
assert_serialization(PromptContextSemanticType::ImgrefBg, "imgref_bg");
|
||||
}
|
||||
}
|
||||
|
||||
mod impl_methods {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn to_str() {
|
||||
assert_eq!(PromptContextSemanticType::VidStartFrame.to_str(), "vid_start_frame");
|
||||
assert_eq!(PromptContextSemanticType::VidEndFrame.to_str(), "vid_end_frame");
|
||||
assert_eq!(PromptContextSemanticType::Imgref.to_str(), "imgref");
|
||||
assert_eq!(PromptContextSemanticType::ImgrefCharacter.to_str(), "imgref_character");
|
||||
assert_eq!(PromptContextSemanticType::ImgrefStyle.to_str(), "imgref_style");
|
||||
assert_eq!(PromptContextSemanticType::ImgrefBg.to_str(), "imgref_bg");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(PromptContextSemanticType::from_str("vid_start_frame").unwrap(), PromptContextSemanticType::VidStartFrame);
|
||||
assert_eq!(PromptContextSemanticType::from_str("vid_end_frame").unwrap(), PromptContextSemanticType::VidEndFrame);
|
||||
assert_eq!(PromptContextSemanticType::from_str("imgref").unwrap(), PromptContextSemanticType::Imgref);
|
||||
assert_eq!(PromptContextSemanticType::from_str("imgref_character").unwrap(), PromptContextSemanticType::ImgrefCharacter);
|
||||
assert_eq!(PromptContextSemanticType::from_str("imgref_style").unwrap(), PromptContextSemanticType::ImgrefStyle);
|
||||
assert_eq!(PromptContextSemanticType::from_str("imgref_bg").unwrap(), PromptContextSemanticType::ImgrefBg);
|
||||
assert!(PromptContextSemanticType::from_str("foo").is_err());
|
||||
}
|
||||
}
|
||||
|
||||
mod manual_variant_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = PromptContextSemanticType::all_variants();
|
||||
assert_eq!(variants.len(), 6);
|
||||
assert_eq!(variants.pop_first(), Some(PromptContextSemanticType::VidStartFrame));
|
||||
assert_eq!(variants.pop_first(), Some(PromptContextSemanticType::VidEndFrame));
|
||||
assert_eq!(variants.pop_first(), Some(PromptContextSemanticType::Imgref));
|
||||
assert_eq!(variants.pop_first(), Some(PromptContextSemanticType::ImgrefCharacter));
|
||||
assert_eq!(variants.pop_first(), Some(PromptContextSemanticType::ImgrefStyle));
|
||||
assert_eq!(variants.pop_first(), Some(PromptContextSemanticType::ImgrefBg));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
mod mechanical_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn variant_length() {
|
||||
use strum::IntoEnumIterator;
|
||||
assert_eq!(PromptContextSemanticType::all_variants().len(), PromptContextSemanticType::iter().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip() {
|
||||
for variant in PromptContextSemanticType::all_variants() {
|
||||
assert_eq!(variant, PromptContextSemanticType::from_str(variant.to_str()).unwrap());
|
||||
assert_eq!(variant, PromptContextSemanticType::from_str(&format!("{}", variant)).unwrap());
|
||||
assert_eq!(variant, PromptContextSemanticType::from_str(&format!("{:?}", variant)).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialized_length_ok_for_database() {
|
||||
const MAX_LENGTH : usize = 16;
|
||||
for variant in PromptContextSemanticType::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,15 @@ use utoipa::ToSchema;
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PromptType {
|
||||
/// Artcraft (App)
|
||||
ArtcraftApp,
|
||||
|
||||
/// Stable diffusion
|
||||
#[deprecated]
|
||||
StableDiffusion,
|
||||
|
||||
/// Comfy UI
|
||||
#[deprecated]
|
||||
ComfyUi,
|
||||
}
|
||||
|
||||
@@ -29,6 +34,7 @@ impl_mysql_from_row!(PromptType);
|
||||
impl PromptType {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::ArtcraftApp => "artcraft_app",
|
||||
Self::StableDiffusion => "stable_diffusion",
|
||||
Self::ComfyUi => "comfy_ui",
|
||||
}
|
||||
@@ -36,6 +42,7 @@ impl PromptType {
|
||||
|
||||
pub fn from_str(value: &str) -> Result<Self, String> {
|
||||
match value {
|
||||
"artcraft_app" => Ok(Self::ArtcraftApp),
|
||||
"stable_diffusion" => Ok(Self::StableDiffusion),
|
||||
"comfy_ui" => Ok(Self::ComfyUi),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
@@ -46,6 +53,7 @@ impl PromptType {
|
||||
// NB: BTreeSet is sorted
|
||||
// NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc.
|
||||
BTreeSet::from([
|
||||
Self::ArtcraftApp,
|
||||
Self::StableDiffusion,
|
||||
Self::ComfyUi,
|
||||
])
|
||||
@@ -62,6 +70,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
assert_serialization(PromptType::ArtcraftApp, "artcraft_app");
|
||||
assert_serialization(PromptType::StableDiffusion, "stable_diffusion");
|
||||
assert_serialization(PromptType::ComfyUi, "comfy_ui");
|
||||
}
|
||||
@@ -72,12 +81,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn to_str() {
|
||||
assert_eq!(PromptType::ArtcraftApp.to_str(), "artcraft_app");
|
||||
assert_eq!(PromptType::StableDiffusion.to_str(), "stable_diffusion");
|
||||
assert_eq!(PromptType::ComfyUi.to_str(), "comfy_ui");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(PromptType::from_str("artcraft_app").unwrap(), PromptType::ArtcraftApp);
|
||||
assert_eq!(PromptType::from_str("stable_diffusion").unwrap(), PromptType::StableDiffusion);
|
||||
assert_eq!(PromptType::from_str("comfy_ui").unwrap(), PromptType::ComfyUi);
|
||||
assert!(PromptType::from_str("foo").is_err());
|
||||
@@ -90,7 +101,8 @@ mod tests {
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = PromptType::all_variants();
|
||||
assert_eq!(variants.len(), 2);
|
||||
assert_eq!(variants.len(), 3);
|
||||
assert_eq!(variants.pop_first(), Some(PromptType::ArtcraftApp));
|
||||
assert_eq!(variants.pop_first(), Some(PromptType::StableDiffusion));
|
||||
assert_eq!(variants.pop_first(), Some(PromptType::ComfyUi));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
|
||||
Reference in new issue
Block a user