codec_eval/corpus/
category.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum ImageCategory {
9 Photo,
11 Illustration,
13 Text,
15 Screenshot,
17 HighFrequency,
19 LowFrequency,
21 Gradient,
23 Pattern,
25 Cgi,
27 Scientific,
29 Other,
31}
32
33impl ImageCategory {
34 #[must_use]
36 pub fn all() -> &'static [Self] {
37 &[
38 Self::Photo,
39 Self::Illustration,
40 Self::Text,
41 Self::Screenshot,
42 Self::HighFrequency,
43 Self::LowFrequency,
44 Self::Gradient,
45 Self::Pattern,
46 Self::Cgi,
47 Self::Scientific,
48 Self::Other,
49 ]
50 }
51
52 #[must_use]
54 pub fn from_str_loose(s: &str) -> Option<Self> {
55 match s.to_lowercase().as_str() {
56 "photo" | "photograph" | "photos" => Some(Self::Photo),
57 "illustration" | "drawing" | "art" | "artwork" => Some(Self::Illustration),
58 "text" | "document" | "docs" => Some(Self::Text),
59 "screenshot" | "screenshots" | "ui" => Some(Self::Screenshot),
60 "high_frequency" | "highfreq" | "texture" | "textures" => Some(Self::HighFrequency),
61 "low_frequency" | "lowfreq" | "smooth" => Some(Self::LowFrequency),
62 "gradient" | "gradients" => Some(Self::Gradient),
63 "pattern" | "patterns" => Some(Self::Pattern),
64 "cgi" | "render" | "3d" => Some(Self::Cgi),
65 "scientific" | "medical" | "science" => Some(Self::Scientific),
66 "other" | "misc" | "unknown" => Some(Self::Other),
67 _ => None,
68 }
69 }
70
71 #[must_use]
73 pub fn description(self) -> &'static str {
74 match self {
75 Self::Photo => "Photographic content",
76 Self::Illustration => "Digital illustrations and artwork",
77 Self::Text => "Text-heavy images and documents",
78 Self::Screenshot => "Screenshots and UI captures",
79 Self::HighFrequency => "High-frequency detail (textures, foliage)",
80 Self::LowFrequency => "Low-frequency content (sky, gradients)",
81 Self::Gradient => "Smooth gradients",
82 Self::Pattern => "Repeating patterns",
83 Self::Cgi => "Computer-generated imagery",
84 Self::Scientific => "Medical or scientific imagery",
85 Self::Other => "Uncategorized",
86 }
87 }
88}
89
90impl std::fmt::Display for ImageCategory {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 match self {
93 Self::Photo => write!(f, "photo"),
94 Self::Illustration => write!(f, "illustration"),
95 Self::Text => write!(f, "text"),
96 Self::Screenshot => write!(f, "screenshot"),
97 Self::HighFrequency => write!(f, "high_frequency"),
98 Self::LowFrequency => write!(f, "low_frequency"),
99 Self::Gradient => write!(f, "gradient"),
100 Self::Pattern => write!(f, "pattern"),
101 Self::Cgi => write!(f, "cgi"),
102 Self::Scientific => write!(f, "scientific"),
103 Self::Other => write!(f, "other"),
104 }
105 }
106}
107
108impl std::str::FromStr for ImageCategory {
109 type Err = String;
110
111 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
112 Self::from_str_loose(s).ok_or_else(|| format!("Unknown category: {s}"))
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 #[test]
121 fn test_category_roundtrip() {
122 for cat in ImageCategory::all() {
123 let s = cat.to_string();
124 let parsed: ImageCategory = s.parse().unwrap();
125 assert_eq!(*cat, parsed);
126 }
127 }
128
129 #[test]
130 fn test_category_from_str_loose() {
131 assert_eq!(
132 ImageCategory::from_str_loose("PHOTO"),
133 Some(ImageCategory::Photo)
134 );
135 assert_eq!(
136 ImageCategory::from_str_loose("Photos"),
137 Some(ImageCategory::Photo)
138 );
139 assert_eq!(
140 ImageCategory::from_str_loose("artwork"),
141 Some(ImageCategory::Illustration)
142 );
143 assert_eq!(ImageCategory::from_str_loose("invalid"), None);
144 }
145}