1use crate::Field;
2use chrono::{DateTime, FixedOffset, Local, NaiveDate, NaiveDateTime};
3use json::{object, JsonValue};
4use std::time::{Duration, UNIX_EPOCH};
5
6pub struct Year {
7 pub require: bool,
8 pub field: String,
9 pub mode: String,
10 pub title: String,
11 pub def: String,
12 pub show: bool,
13 pub describe: String,
14 pub example: JsonValue,
15}
16
17impl Year {
18 pub fn new(require: bool, field: &str, title: &str, default: &str) -> Self {
19 Self {
20 field: field.to_string(),
21 mode: "year".to_string(),
22 title: title.to_string(),
23 def: default.to_string(),
24 require,
25 show: true,
26 describe: String::new(),
27 example: JsonValue::Null,
28 }
29 }
30 pub fn year() -> String {
31 let now: DateTime<Local> = Local::now();
32 let dft = now.format("%Y");
33 dft.to_string()
34 }
35 pub fn timestamp_to_year(timestamp: i64) -> String {
36 let d = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
37 let datetime = DateTime::<Local>::from(d);
38 let timestamp_str = datetime.format("%Y").to_string();
39 timestamp_str
40 }
41}
42
43impl Field for Year {
44 fn sql(&mut self, model: &str) -> String {
45 let not_null = if self.require { " not null" } else { "" };
46 match model {
47 "sqlite" => format!("{} INTEGER{} default '{}'", self.field, not_null, self.def),
48 "pgsql" => {
49 format!(
50 r#""{}" SMALLINT{} default '{}'"#,
51 self.field, not_null, self.def
52 )
53 }
54 _ => {
55 let sql = format!("`{}` year{} default '{}'", self.field, not_null, self.def);
56 format!(
57 "{} comment '{}|{}|{}|{}'",
58 sql.clone(),
59 self.title,
60 self.mode,
61 self.require,
62 self.def
63 )
64 }
65 }
66 }
67 fn hide(&mut self) -> &mut Self {
68 self.show = false;
69 self
70 }
71
72 fn describe(&mut self, text: &str) -> &mut Self {
73 self.describe = text.to_string();
74 self
75 }
76
77 fn field(&mut self) -> JsonValue {
78 let mut field = object! {};
79 field
80 .insert("require", JsonValue::from(self.require))
81 .unwrap();
82 field
83 .insert("field", JsonValue::from(self.field.clone()))
84 .unwrap();
85 field
86 .insert("mode", JsonValue::from(self.mode.clone()))
87 .unwrap();
88 field
89 .insert("title", JsonValue::from(self.title.clone()))
90 .unwrap();
91 field
92 .insert("def", JsonValue::from(self.def.clone()))
93 .unwrap();
94 field.insert("show", JsonValue::from(self.show)).unwrap();
95 field
96 .insert("describe", JsonValue::from(self.describe.clone()))
97 .unwrap();
98 field.insert("example", self.example.clone()).unwrap();
99 field
100 }
101
102 fn swagger(&mut self) -> JsonValue {
103 object! {
104 "type": self.mode.clone(),
105 "example": self.example.clone(),
106 }
107 }
108 fn example(&mut self, data: JsonValue) -> &mut Self {
109 self.example = data.clone();
110 self
111 }
112}
113
114pub struct YearMonth {
122 pub require: bool,
123 pub field: String,
124 pub mode: String,
125 pub title: String,
126 pub def: i64,
127 pub show: bool,
128 pub describe: String,
129 pub example: JsonValue,
130}
131
132impl YearMonth {
133 pub fn new(require: bool, field: &str, title: &str, default: i64) -> Self {
134 Self {
135 field: field.to_string(),
136 mode: "yearmonth".to_string(),
137 title: title.to_string(),
138 def: default,
139 require,
140 show: true,
141 describe: String::new(),
142 example: JsonValue::Null,
143 }
144 }
145 pub fn year_month() -> i64 {
147 let now: DateTime<Local> = Local::now();
148 let first_day = format!("{}-01 00:00:00", now.format("%Y-%m"));
149 let t = NaiveDateTime::parse_from_str(&first_day, "%Y-%m-%d %H:%M:%S").unwrap();
150 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
151 t.and_local_timezone(tz).unwrap().timestamp()
152 }
153 #[allow(clippy::should_implement_trait)]
154 pub fn from_str(year_month: &str) -> i64 {
156 let date_str = if year_month.len() == 7 {
157 format!("{}-01 00:00:00", year_month)
158 } else {
159 format!("{} 00:00:00", year_month)
160 };
161 let t = NaiveDateTime::parse_from_str(&date_str, "%Y-%m-%d %H:%M:%S").unwrap();
162 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
163 t.and_local_timezone(tz).unwrap().timestamp()
164 }
165 pub fn to_str(timestamp: i64) -> String {
167 let d = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
168 let datetime = DateTime::<Local>::from(d);
169 datetime.format("%Y-%m").to_string()
170 }
171}
172
173impl Field for YearMonth {
174 fn sql(&mut self, model: &str) -> String {
175 let not_null = if self.require { " not null" } else { "" };
176 let max = 10;
177 match model {
178 "sqlite" => {
179 format!("{} REAL{} default {}", self.field, not_null, self.def)
180 }
181 "pgsql" => {
182 format!(
183 r#""{}" decimal({},0){} default {}"#,
184 self.field, max, not_null, self.def
185 )
186 }
187 _ => {
188 let sql = format!(
189 "`{}` decimal({},0){} default {}",
190 self.field, max, not_null, self.def
191 );
192 format!(
193 "{} comment '{}|{}|{}|{}'",
194 sql.clone(),
195 self.title,
196 self.mode,
197 self.require,
198 self.def
199 )
200 }
201 }
202 }
203 fn hide(&mut self) -> &mut Self {
204 self.show = false;
205 self
206 }
207
208 fn describe(&mut self, text: &str) -> &mut Self {
209 self.describe = text.to_string();
210 self
211 }
212
213 fn field(&mut self) -> JsonValue {
214 let mut field = object! {};
215 field
216 .insert("require", JsonValue::from(self.require))
217 .unwrap();
218 field
219 .insert("field", JsonValue::from(self.field.clone()))
220 .unwrap();
221 field
222 .insert("mode", JsonValue::from(self.mode.clone()))
223 .unwrap();
224 field
225 .insert("title", JsonValue::from(self.title.clone()))
226 .unwrap();
227 field.insert("def", JsonValue::from(self.def)).unwrap();
228 field.insert("show", JsonValue::from(self.show)).unwrap();
229 field
230 .insert("describe", JsonValue::from(self.describe.clone()))
231 .unwrap();
232 field.insert("example", self.example.clone()).unwrap();
233 field
234 }
235
236 fn swagger(&mut self) -> JsonValue {
237 object! {
238 "type": self.mode.clone(),
239 "example": self.example.clone(),
240 }
241 }
242 fn example(&mut self, data: JsonValue) -> &mut Self {
243 self.example = data.clone();
244 self
245 }
246}
247
248pub struct Datetime {
249 pub require: bool,
250 pub field: String,
251 pub mode: String,
252 pub title: String,
253 pub def: String,
254 pub show: bool,
255 pub describe: String,
256 pub example: JsonValue,
257}
258
259impl Datetime {
260 pub fn new(require: bool, field: &str, title: &str, mut default: &str) -> Self {
261 if default.is_empty() {
262 default = "0001-01-01 00:00:00";
263 }
264 Self {
265 field: field.to_string(),
266 mode: "datetime".to_string(),
267 title: title.to_string(),
268 def: default.to_string(),
269 require,
270 show: true,
271 describe: String::new(),
272 example: JsonValue::Null,
273 }
274 }
275 pub fn datetime() -> String {
276 let now: DateTime<Local> = Local::now();
277 let dft = now.format("%Y-%m-%d %H:%M:%S");
278 dft.to_string()
279 }
280 pub fn timestamp_to_datetime(timestamp: i64) -> String {
281 let d = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
282 let datetime = DateTime::<Local>::from(d);
283 let timestamp_str = datetime.format("%Y-%m-%d %H:%M:%S").to_string();
284 timestamp_str
285 }
286 pub fn datetime_format(format: &str) -> String {
287 let now: DateTime<Local> = Local::now();
288 let dft = now.format(format);
289 dft.to_string()
290 }
291}
292
293impl Field for Datetime {
294 fn sql(&mut self, model: &str) -> String {
295 let not_null = if self.require { " not null" } else { "" };
296 match model {
297 "sqlite" => format!("{} datetime{} default '{}'", self.field, not_null, self.def),
298 "pgsql" => {
299 format!(
300 r#""{}" timestamp{} default '{}'"#,
301 self.field, not_null, self.def
302 )
303 }
304 _ => {
305 let sql = format!(
306 "`{}` datetime{} default '{}'",
307 self.field, not_null, self.def
308 );
309 format!(
310 "{} comment '{}|{}|{}|{}'",
311 sql.clone(),
312 self.title,
313 self.mode,
314 self.require,
315 self.def
316 )
317 }
318 }
319 }
320 fn hide(&mut self) -> &mut Self {
321 self.show = false;
322 self
323 }
324 fn describe(&mut self, text: &str) -> &mut Self {
325 self.describe = text.to_string();
326 self
327 }
328
329 fn field(&mut self) -> JsonValue {
330 let mut field = object! {};
331 field
332 .insert("require", JsonValue::from(self.require))
333 .unwrap();
334 field
335 .insert("field", JsonValue::from(self.field.clone()))
336 .unwrap();
337 field
338 .insert("mode", JsonValue::from(self.mode.clone()))
339 .unwrap();
340 field
341 .insert("title", JsonValue::from(self.title.clone()))
342 .unwrap();
343 field
344 .insert("def", JsonValue::from(self.def.clone()))
345 .unwrap();
346
347 field.insert("show", JsonValue::from(self.show)).unwrap();
348 field
349 .insert("describe", JsonValue::from(self.describe.clone()))
350 .unwrap();
351 field.insert("example", self.example.clone()).unwrap();
352 field
353 }
354
355 fn swagger(&mut self) -> JsonValue {
356 object! {
357 "type": self.mode.clone(),
358 "example": self.example.clone(),
359 }
360 }
361 fn example(&mut self, data: JsonValue) -> &mut Self {
362 self.example = data.clone();
363 self
364 }
365}
366#[derive(Debug, Clone)]
367pub struct Time {
368 pub require: bool,
369 pub field: String,
370 pub mode: String,
371 pub title: String,
372 pub def: String,
373 pub show: bool,
374 pub describe: String,
375 pub example: JsonValue,
376}
377
378impl Time {
379 pub fn new(require: bool, field: &str, title: &str, default: &str) -> Self {
380 Self {
381 field: field.to_string(),
382 mode: "time".to_string(),
383 title: title.to_string(),
384 def: default.to_string(),
385 require,
386 show: true,
387 describe: String::new(),
388 example: JsonValue::Null,
389 }
390 }
391 pub fn time() -> String {
392 let now: DateTime<Local> = Local::now();
393 let dft = now.format("%H:%M:%S");
394 dft.to_string()
395 }
396}
397
398impl Field for Time {
399 fn sql(&mut self, model: &str) -> String {
400 let not_null = if self.require { " not null" } else { "" };
401 match model {
402 "sqlite" => format!("{} time{} default '{}'", self.field, not_null, self.def),
403 "pgsql" => {
404 format!(
405 r#""{}" time{} default '{}'"#,
406 self.field, not_null, self.def
407 )
408 }
409 _ => {
410 let sql = format!("`{}` time{} default '{}'", self.field, not_null, self.def);
411 format!(
412 "{} comment '{}|{}|{}|{}'",
413 sql.clone(),
414 self.title,
415 self.mode,
416 self.require,
417 self.def
418 )
419 }
420 }
421 }
422 fn hide(&mut self) -> &mut Self {
423 self.show = false;
424 self
425 }
426
427 fn describe(&mut self, text: &str) -> &mut Self {
428 self.describe = text.to_string();
429 self
430 }
431
432 fn field(&mut self) -> JsonValue {
433 let mut field = object! {};
434 field
435 .insert("require", JsonValue::from(self.require))
436 .unwrap();
437 field
438 .insert("field", JsonValue::from(self.field.clone()))
439 .unwrap();
440 field
441 .insert("mode", JsonValue::from(self.mode.clone()))
442 .unwrap();
443 field
444 .insert("title", JsonValue::from(self.title.clone()))
445 .unwrap();
446 field
447 .insert("def", JsonValue::from(self.def.clone()))
448 .unwrap();
449
450 field.insert("show", JsonValue::from(self.show)).unwrap();
451 field
452 .insert("describe", JsonValue::from(self.describe.clone()))
453 .unwrap();
454 field.insert("example", self.example.clone()).unwrap();
455 field
456 }
457
458 fn swagger(&mut self) -> JsonValue {
459 object! {
460 "type": self.mode.clone(),
461 "example": self.example.clone(),
462 }
463 }
464 fn example(&mut self, data: JsonValue) -> &mut Self {
465 self.example = data.clone();
466 self
467 }
468}
469#[derive(Debug, Clone)]
470pub struct Date {
471 pub require: bool,
472 pub field: String,
473 pub mode: String,
474 pub title: String,
475 pub def: String,
476 pub show: bool,
477 pub describe: String,
478 pub example: JsonValue,
479}
480
481impl Date {
482 pub fn new(require: bool, field: &str, title: &str, default: &str) -> Self {
483 let def = {
484 if default.is_empty() {
485 "0001-01-01"
486 } else {
487 default
488 }
489 };
490 Self {
491 field: field.to_string(),
492 mode: "date".to_string(),
493 title: title.to_string(),
494 def: def.parse().unwrap(),
495 require,
496 show: true,
497 describe: "".to_string(),
498 example: JsonValue::Null,
499 }
500 }
501 pub fn date() -> String {
503 let now: DateTime<Local> = Local::now();
504 let dft = now.format("%Y-%m-%d");
505 dft.to_string()
506 }
507 pub fn timestamp_to_date(timestamp: i64) -> String {
508 let d = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
509 let datetime = DateTime::<Local>::from(d);
510 let timestamp_str = datetime.format("%Y-%m-%d").to_string();
511 timestamp_str
512 }
513}
514
515impl Field for Date {
516 fn sql(&mut self, model: &str) -> String {
517 let not_null = if self.require { " not null" } else { "" };
518 match model {
519 "sqlite" => format!("{} date{} default '{}'", self.field, not_null, self.def),
520 "pgsql" => {
521 format!(
522 r#""{}" date{} default '{}'"#,
523 self.field, not_null, self.def
524 )
525 }
526 _ => {
527 let sql = format!("`{}` date{} default '{}'", self.field, not_null, self.def);
528 format!(
529 "{} comment '{}|{}|{}|{}'",
530 sql.clone(),
531 self.title,
532 self.mode,
533 self.require,
534 self.def
535 )
536 }
537 }
538 }
539 fn hide(&mut self) -> &mut Self {
540 self.show = false;
541 self
542 }
543
544 fn describe(&mut self, text: &str) -> &mut Self {
545 self.describe = text.to_string();
546 self
547 }
548
549 fn field(&mut self) -> JsonValue {
550 let mut field = object! {};
551 field
552 .insert("require", JsonValue::from(self.require))
553 .unwrap();
554 field
555 .insert("field", JsonValue::from(self.field.clone()))
556 .unwrap();
557 field
558 .insert("mode", JsonValue::from(self.mode.clone()))
559 .unwrap();
560 field
561 .insert("title", JsonValue::from(self.title.clone()))
562 .unwrap();
563 field
564 .insert("def", JsonValue::from(self.def.clone()))
565 .unwrap();
566
567 field.insert("show", JsonValue::from(self.show)).unwrap();
568 field
569 .insert("describe", JsonValue::from(self.describe.clone()))
570 .unwrap();
571 field.insert("example", self.example.clone()).unwrap();
572 field
573 }
574 fn swagger(&mut self) -> JsonValue {
575 object! {
576 "type": self.mode.clone(),
577 "example": self.example.clone(),
578 }
579 }
580 fn example(&mut self, data: JsonValue) -> &mut Self {
581 self.example = data.clone();
582 self
583 }
584}
585#[derive(Debug, Clone)]
586pub struct Timestamp {
587 pub require: bool,
588 pub field: String,
589 pub mode: String,
590 pub title: String,
591 pub def: f64,
592 pub dec: i32,
593 pub show: bool,
594 pub describe: String,
595 pub example: JsonValue,
596}
597
598impl Timestamp {
599 pub fn new(require: bool, field: &str, title: &str, dec: i32, default: f64) -> Self {
600 Self {
601 require,
602 field: field.to_string(),
603 mode: "timestamp".to_string(),
604 title: title.to_string(),
605 def: default,
606 dec,
607 show: true,
608 describe: "".to_string(),
609 example: JsonValue::Null,
610 }
611 }
612 pub fn timestamp() -> i64 {
614 Local::now().timestamp()
615 }
616 pub fn timestamp_ms() -> i64 {
618 Local::now().timestamp_millis()
619 }
620 pub fn timestamp_ms_f64() -> f64 {
622 Local::now().timestamp_millis() as f64 / 1000.0
623 }
624 pub fn timestamp_μs() -> i64 {
626 Local::now().timestamp_micros()
627 }
628 pub fn timestamp_μs_f64() -> f64 {
630 Local::now().timestamp_micros() as f64 / 1000.0 / 1000.0
631 }
632 pub fn timestamp_ns() -> i64 {
634 Local::now().timestamp_nanos_opt().unwrap()
635 }
636
637 pub fn date_to_timestamp(date: &str) -> i64 {
639 let t = NaiveDate::parse_from_str(date, "%Y-%m-%d").unwrap();
640 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
641 t.and_hms_opt(0, 0, 0)
642 .unwrap()
643 .and_local_timezone(tz)
644 .unwrap()
645 .timestamp()
646 }
647 pub fn datetime_to_rfc2822(datetime: &str) -> String {
649 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
650 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
651 t.and_local_timezone(tz).unwrap().to_rfc2822()
652 }
653 pub fn datetime_utc_rfc2822(datetime: &str) -> String {
654 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
655 t.and_utc().to_rfc2822()
656 }
657 pub fn datetime_to_fmt(datetime: &str, fmt: &str) -> String {
658 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
659 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
660 t.and_local_timezone(tz).unwrap().format(fmt).to_string()
661 }
662 pub fn datetime_to_timestamp(datetime: &str, fmt: &str) -> i64 {
663 let t = NaiveDateTime::parse_from_str(datetime, fmt).unwrap();
664 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
665 t.and_local_timezone(tz).unwrap().timestamp()
666 }
667 pub fn datetime_timestamp(datetime: &str) -> i64 {
668 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
669 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
670 t.and_local_timezone(tz).unwrap().timestamp()
671 }
672}
673
674impl Field for Timestamp {
675 fn sql(&mut self, model: &str) -> String {
676 let not_null = if self.require { " not null" } else { "" };
677 let max = 10 + self.dec;
678 match model {
679 "sqlite" => {
680 let def = format!("{0:.width$}", self.def, width = self.dec as usize)
681 .parse::<f64>()
682 .unwrap();
683 format!("{} REAL{} default {}", self.field, not_null, def)
684 }
685 "pgsql" => {
686 let def = format!("{0:.width$}", self.def, width = self.dec as usize);
687 let def_value = def.parse::<f64>().unwrap();
688 format!(
689 r#""{}" decimal({},{}){} default {}"#,
690 self.field, max, self.dec, not_null, def_value
691 )
692 }
693 _ => {
694 let def = format!("{0:.width$}", self.def, width = self.dec as usize);
695 let def_value = def.parse::<f64>().unwrap();
696 let sql = format!(
697 "`{}` decimal({},{}){} default {}",
698 self.field, max, self.dec, not_null, def_value
699 );
700 format!(
701 "{} comment '{}|{}|{}|{}|{}'",
702 sql.clone(),
703 self.title,
704 self.mode,
705 self.require,
706 self.dec,
707 def_value
708 )
709 }
710 }
711 }
712 fn hide(&mut self) -> &mut Self {
713 self.show = false;
714 self
715 }
716
717 fn describe(&mut self, text: &str) -> &mut Self {
718 self.describe = text.to_string();
719 self
720 }
721
722 fn field(&mut self) -> JsonValue {
723 let mut field = object! {};
724 field
725 .insert("require", JsonValue::from(self.require))
726 .unwrap();
727 field
728 .insert("field", JsonValue::from(self.field.clone()))
729 .unwrap();
730 field
731 .insert("mode", JsonValue::from(self.mode.clone()))
732 .unwrap();
733 field
734 .insert("title", JsonValue::from(self.title.clone()))
735 .unwrap();
736 field.insert("def", JsonValue::from(self.def)).unwrap();
737 field.insert("dec", JsonValue::from(self.dec)).unwrap();
738 field.insert("show", JsonValue::from(self.show)).unwrap();
739 field
740 .insert("describe", JsonValue::from(self.describe.clone()))
741 .unwrap();
742 field.insert("example", self.example.clone()).unwrap();
743 field
744 }
745
746 fn swagger(&mut self) -> JsonValue {
747 object! {
748 "type": self.mode.clone(),
749 "example": self.example.clone(),
750 }
751 }
752
753 fn example(&mut self, data: JsonValue) -> &mut Self {
754 self.example = data.clone();
755 self
756 }
757}