1use crate::define_text_subtype;
72
73define_text_subtype!(Plain, "plain");
76define_text_subtype!(MultiLine, "multiline", multiline: true);
77
78define_text_subtype!(Email, "email", pattern: r"^[^@\s]+@[^@\s]+\.[^@\s]+$", placeholder: "user@example.com");
81define_text_subtype!(Url, "url", pattern: r"^https?://", placeholder: "https://example.com");
82define_text_subtype!(Domain, "domain", placeholder: "example.com");
83define_text_subtype!(IpAddressV4, "ip_v4", pattern: r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", placeholder: "192.168.1.1");
84define_text_subtype!(IpAddressV6, "ip_v6", placeholder: "::1");
85define_text_subtype!(Hostname, "hostname", placeholder: "localhost");
86define_text_subtype!(MacAddress, "mac_address", pattern: r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", placeholder: "00:1A:2B:3C:4D:5E");
87
88define_text_subtype!(FilePath, "file_path", placeholder: "/path/to/file");
91define_text_subtype!(DirPath, "dir_path", placeholder: "/path/to/directory");
92define_text_subtype!(FileName, "file_name", placeholder: "filename.ext");
93
94define_text_subtype!(Secret, "secret", sensitive: true);
97define_text_subtype!(Password, "password", sensitive: true);
98define_text_subtype!(ApiKey, "api_key", sensitive: true);
99define_text_subtype!(BearerToken, "bearer_token", sensitive: true);
100
101define_text_subtype!(Uuid, "uuid", pattern: r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", placeholder: "00000000-0000-0000-0000-000000000000");
104define_text_subtype!(Slug, "slug", pattern: r"^[a-z0-9]+(?:-[a-z0-9]+)*$", placeholder: "my-slug");
105
106define_text_subtype!(DateTime, "datetime", placeholder: "2024-01-01T00:00:00Z");
109define_text_subtype!(Date, "date", pattern: r"^\d{4}-\d{2}-\d{2}$", placeholder: "2024-01-01");
110define_text_subtype!(Time, "time", pattern: r"^\d{2}:\d{2}(:\d{2})?$", placeholder: "12:00:00");
111define_text_subtype!(Iso8601Duration, "iso8601_duration", pattern: r"^P", placeholder: "PT1H30M");
112define_text_subtype!(Cron, "cron", placeholder: "*/5 * * * *");
113define_text_subtype!(Timezone, "timezone", placeholder: "America/New_York");
114
115define_text_subtype!(Json, "json", multiline: true);
118define_text_subtype!(Yaml, "yaml", multiline: true);
119define_text_subtype!(Toml, "toml", multiline: true);
120define_text_subtype!(Xml, "xml", multiline: true);
121define_text_subtype!(Markdown, "markdown", multiline: true);
122define_text_subtype!(Html, "html", multiline: true);
123
124define_text_subtype!(Sql, "sql", code: "sql");
127define_text_subtype!(Regex, "regex", placeholder: "^pattern$");
128define_text_subtype!(Expression, "expression", placeholder: "{{ value }}");
129define_text_subtype!(JavaScript, "javascript", code: "javascript");
130define_text_subtype!(Python, "python", code: "python");
131define_text_subtype!(Rust, "rust", code: "rust");
132
133define_text_subtype!(PhoneNumber, "phone_number", placeholder: "+1 555 123 4567");
136
137define_text_subtype!(HexColor, "hex_color", pattern: r"^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$", placeholder: "#FF5733");
140
141define_text_subtype!(Country, "country", pattern: r"^[A-Z]{2}$", placeholder: "US");
144define_text_subtype!(Language, "language", pattern: r"^[a-z]{2}(-[A-Z]{2})?$", placeholder: "en");
145define_text_subtype!(CurrencyCode, "currency_code", pattern: r"^[A-Z]{3}$", placeholder: "USD");
146
147define_text_subtype!(Semver, "semver", pattern: r"^\d+\.\d+\.\d+", placeholder: "1.0.0");
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154 use crate::subtype::TextSubtype;
155
156 #[test]
159 fn test_plain() {
160 assert_eq!(Plain::name(), "plain");
161 assert!(!Plain::is_multiline());
162 assert!(!Plain::is_sensitive());
163 }
164
165 #[test]
166 fn test_multiline() {
167 assert_eq!(MultiLine::name(), "multiline");
168 assert!(MultiLine::is_multiline());
169 }
170
171 #[test]
174 fn test_email() {
175 assert_eq!(Email::name(), "email");
176 assert!(Email::pattern().is_some());
177 assert_eq!(Email::placeholder(), Some("user@example.com"));
178 }
179
180 #[test]
181 fn test_url() {
182 assert_eq!(Url::name(), "url");
183 assert!(Url::pattern().is_some());
184 assert_eq!(Url::placeholder(), Some("https://example.com"));
185 }
186
187 #[test]
188 fn test_domain() {
189 assert_eq!(Domain::name(), "domain");
190 assert_eq!(Domain::placeholder(), Some("example.com"));
191 }
192
193 #[test]
194 fn test_ip_v4() {
195 assert_eq!(IpAddressV4::name(), "ip_v4");
196 assert!(IpAddressV4::pattern().is_some());
197 }
198
199 #[test]
200 fn test_ip_v6() {
201 assert_eq!(IpAddressV6::name(), "ip_v6");
202 }
203
204 #[test]
205 fn test_hostname() {
206 assert_eq!(Hostname::name(), "hostname");
207 assert_eq!(Hostname::placeholder(), Some("localhost"));
208 }
209
210 #[test]
213 fn test_file_path() {
214 assert_eq!(FilePath::name(), "file_path");
215 }
216
217 #[test]
218 fn test_dir_path() {
219 assert_eq!(DirPath::name(), "dir_path");
220 }
221
222 #[test]
223 fn test_file_name() {
224 assert_eq!(FileName::name(), "file_name");
225 }
226
227 #[test]
230 fn test_secret() {
231 assert_eq!(Secret::name(), "secret");
232 assert!(Secret::is_sensitive());
233 }
234
235 #[test]
236 fn test_password() {
237 assert_eq!(Password::name(), "password");
238 assert!(Password::is_sensitive());
239 }
240
241 #[test]
242 fn test_api_key() {
243 assert_eq!(ApiKey::name(), "api_key");
244 assert!(ApiKey::is_sensitive());
245 }
246
247 #[test]
248 fn test_bearer_token() {
249 assert_eq!(BearerToken::name(), "bearer_token");
250 assert!(BearerToken::is_sensitive());
251 }
252
253 #[test]
256 fn test_uuid() {
257 assert_eq!(Uuid::name(), "uuid");
258 assert!(Uuid::pattern().is_some());
259 }
260
261 #[test]
262 fn test_slug() {
263 assert_eq!(Slug::name(), "slug");
264 assert!(Slug::pattern().is_some());
265 }
266
267 #[test]
270 fn test_datetime() {
271 assert_eq!(DateTime::name(), "datetime");
272 }
273
274 #[test]
275 fn test_date() {
276 assert_eq!(Date::name(), "date");
277 assert!(Date::pattern().is_some());
278 }
279
280 #[test]
281 fn test_time() {
282 assert_eq!(Time::name(), "time");
283 assert!(Time::pattern().is_some());
284 }
285
286 #[test]
289 fn test_json() {
290 assert_eq!(Json::name(), "json");
291 assert!(Json::is_multiline());
292 }
293
294 #[test]
295 fn test_yaml() {
296 assert_eq!(Yaml::name(), "yaml");
297 assert!(Yaml::is_multiline());
298 }
299
300 #[test]
301 fn test_toml() {
302 assert_eq!(Toml::name(), "toml");
303 assert!(Toml::is_multiline());
304 }
305
306 #[test]
307 fn test_xml() {
308 assert_eq!(Xml::name(), "xml");
309 assert!(Xml::is_multiline());
310 }
311
312 #[test]
315 fn test_sql() {
316 assert_eq!(Sql::name(), "sql");
317 assert!(Sql::is_multiline());
318 assert_eq!(Sql::code_language(), Some("sql"));
319 }
320
321 #[test]
322 fn test_regex() {
323 assert_eq!(Regex::name(), "regex");
324 assert_eq!(Regex::placeholder(), Some("^pattern$"));
325 }
326
327 #[test]
328 fn test_expression() {
329 assert_eq!(Expression::name(), "expression");
330 }
331
332 #[test]
333 fn test_javascript() {
334 assert_eq!(JavaScript::name(), "javascript");
335 assert_eq!(JavaScript::code_language(), Some("javascript"));
336 }
337
338 #[test]
339 fn test_python() {
340 assert_eq!(Python::name(), "python");
341 assert_eq!(Python::code_language(), Some("python"));
342 }
343
344 #[test]
345 fn test_rust() {
346 assert_eq!(Rust::name(), "rust");
347 assert_eq!(Rust::code_language(), Some("rust"));
348 }
349
350 #[test]
353 fn test_mac_address() {
354 assert_eq!(MacAddress::name(), "mac_address");
355 assert!(MacAddress::pattern().is_some());
356 assert_eq!(MacAddress::placeholder(), Some("00:1A:2B:3C:4D:5E"));
357 }
358
359 #[test]
362 fn test_iso8601_duration() {
363 assert_eq!(Iso8601Duration::name(), "iso8601_duration");
364 assert!(Iso8601Duration::pattern().is_some());
365 assert_eq!(Iso8601Duration::placeholder(), Some("PT1H30M"));
366 }
367
368 #[test]
369 fn test_cron() {
370 assert_eq!(Cron::name(), "cron");
371 assert_eq!(Cron::placeholder(), Some("*/5 * * * *"));
372 }
373
374 #[test]
375 fn test_timezone() {
376 assert_eq!(Timezone::name(), "timezone");
377 assert_eq!(Timezone::placeholder(), Some("America/New_York"));
378 }
379
380 #[test]
383 fn test_markdown() {
384 assert_eq!(Markdown::name(), "markdown");
385 assert!(Markdown::is_multiline());
386 }
387
388 #[test]
389 fn test_html() {
390 assert_eq!(Html::name(), "html");
391 assert!(Html::is_multiline());
392 }
393
394 #[test]
397 fn test_phone_number() {
398 assert_eq!(PhoneNumber::name(), "phone_number");
399 assert_eq!(PhoneNumber::placeholder(), Some("+1 555 123 4567"));
400 }
401
402 #[test]
405 fn test_hex_color() {
406 assert_eq!(HexColor::name(), "hex_color");
407 assert!(HexColor::pattern().is_some());
408 assert_eq!(HexColor::placeholder(), Some("#FF5733"));
409 }
410
411 #[test]
414 fn test_country() {
415 assert_eq!(Country::name(), "country");
416 assert!(Country::pattern().is_some());
417 assert_eq!(Country::placeholder(), Some("US"));
418 }
419
420 #[test]
421 fn test_language() {
422 assert_eq!(Language::name(), "language");
423 assert!(Language::pattern().is_some());
424 assert_eq!(Language::placeholder(), Some("en"));
425 }
426
427 #[test]
428 fn test_currency_code() {
429 assert_eq!(CurrencyCode::name(), "currency_code");
430 assert!(CurrencyCode::pattern().is_some());
431 assert_eq!(CurrencyCode::placeholder(), Some("USD"));
432 }
433
434 #[test]
437 fn test_semver() {
438 assert_eq!(Semver::name(), "semver");
439 assert!(Semver::pattern().is_some());
440 assert_eq!(Semver::placeholder(), Some("1.0.0"));
441 }
442}