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!(
48 "`{}` INTEGER{} default '{}'",
49 self.field, not_null, self.def
50 ),
51 "pgsql" => {
52 let sql = format!(r#""{}" SMALLINT default '{}'"#, self.field, self.def);
53 format!(
54 "{} --{}|{}|{}|{}",
55 sql, self.title, self.mode, self.require, self.def
56 )
57 }
58 _ => {
59 let sql = format!("`{}` year{} default '{}'", self.field, not_null, self.def);
60 format!(
61 "{} comment '{}|{}|{}|{}'",
62 sql, self.title, self.mode, self.require, 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 fn field(&mut self) -> JsonValue {
77 let mut field = object! {};
78 field
79 .insert("require", JsonValue::from(self.require))
80 .unwrap();
81 field
82 .insert("field", JsonValue::from(self.field.clone()))
83 .unwrap();
84 field
85 .insert("mode", JsonValue::from(self.mode.clone()))
86 .unwrap();
87 field
88 .insert("title", JsonValue::from(self.title.clone()))
89 .unwrap();
90 field
91 .insert("def", JsonValue::from(self.def.clone()))
92 .unwrap();
93
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 let sql = format!(
183 r#""{}" decimal({},0) default {}"#,
184 self.field, max, self.def
185 );
186 format!(
187 "{} --{}|{}|{}|{}",
188 sql, self.title, self.mode, self.require, self.def
189 )
190 }
191 _ => {
192 let sql = format!(
193 "`{}` decimal({},0){} default {}",
194 self.field, max, not_null, self.def
195 );
196 format!(
197 "{} comment '{}|{}|{}|{}'",
198 sql, self.title, self.mode, self.require, 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: i64,
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, default: i64) -> Self {
261 Self {
262 field: field.to_string(),
263 mode: "datetime".to_string(),
264 title: title.to_string(),
265 def: default,
266 require,
267 show: true,
268 describe: String::new(),
269 example: JsonValue::Null,
270 }
271 }
272 pub fn datetime() -> i64 {
274 Local::now().timestamp()
275 }
276 pub fn timestamp_to_datetime(timestamp: i64) -> String {
278 let d = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
279 let datetime = DateTime::<Local>::from(d);
280 datetime.format("%Y-%m-%d %H:%M:%S").to_string()
281 }
282 pub fn datetime_to_timestamp(datetime: &str) -> i64 {
284 if datetime.is_empty() || datetime == "0001-01-01 00:00:00" {
285 return 0;
286 }
287 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S");
288 match t {
289 Ok(d) => {
290 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
291 d.and_local_timezone(tz).unwrap().timestamp()
292 }
293 Err(_) => 0,
294 }
295 }
296 pub fn datetime_format(format: &str) -> String {
297 let now: DateTime<Local> = Local::now();
298 let dft = now.format(format);
299 dft.to_string()
300 }
301}
302
303impl Field for Datetime {
304 fn sql(&mut self, model: &str) -> String {
305 let not_null = if self.require { " not null" } else { "" };
306 let max = 10;
307 match model {
308 "sqlite" => {
309 format!("`{}` REAL{} default {}", self.field, not_null, self.def)
310 }
311 "pgsql" => {
312 let sql = format!(
313 r#""{}" decimal({},0) default {}"#,
314 self.field, max, self.def
315 );
316 format!(
317 "{} --{}|{}|{}|{}",
318 sql, self.title, self.mode, self.require, self.def
319 )
320 }
321 _ => {
322 let sql = format!(
323 "`{}` decimal({},0){} default {}",
324 self.field, max, not_null, self.def
325 );
326 format!(
327 "{} comment '{}|{}|{}|{}'",
328 sql, self.title, self.mode, self.require, self.def
329 )
330 }
331 }
332 }
333 fn hide(&mut self) -> &mut Self {
334 self.show = false;
335 self
336 }
337 fn describe(&mut self, text: &str) -> &mut Self {
338 self.describe = text.to_string();
339 self
340 }
341
342 fn field(&mut self) -> JsonValue {
343 let mut field = object! {};
344 field
345 .insert("require", JsonValue::from(self.require))
346 .unwrap();
347 field
348 .insert("field", JsonValue::from(self.field.clone()))
349 .unwrap();
350 field
351 .insert("mode", JsonValue::from(self.mode.clone()))
352 .unwrap();
353 field
354 .insert("title", JsonValue::from(self.title.clone()))
355 .unwrap();
356 field
357 .insert("def", JsonValue::from(self.def))
358 .unwrap();
359
360 field.insert("show", JsonValue::from(self.show)).unwrap();
361 field
362 .insert("describe", JsonValue::from(self.describe.clone()))
363 .unwrap();
364 field.insert("example", self.example.clone()).unwrap();
365 field
366 }
367
368 fn swagger(&mut self) -> JsonValue {
369 object! {
370 "type": self.mode.clone(),
371 "example": self.example.clone(),
372 }
373 }
374 fn example(&mut self, data: JsonValue) -> &mut Self {
375 self.example = data.clone();
376 self
377 }
378}
379#[derive(Debug, Clone)]
380pub struct Time {
381 pub require: bool,
382 pub field: String,
383 pub mode: String,
384 pub title: String,
385 pub def: String,
386 pub show: bool,
387 pub describe: String,
388 pub example: JsonValue,
389}
390
391impl Time {
392 pub fn new(require: bool, field: &str, title: &str, default: &str) -> Self {
393 Self {
394 field: field.to_string(),
395 mode: "time".to_string(),
396 title: title.to_string(),
397 def: default.to_string(),
398 require,
399 show: true,
400 describe: String::new(),
401 example: JsonValue::Null,
402 }
403 }
404 pub fn time() -> String {
405 let now: DateTime<Local> = Local::now();
406 let dft = now.format("%H:%M:%S");
407 dft.to_string()
408 }
409}
410
411impl Field for Time {
412 fn sql(&mut self, model: &str) -> String {
413 let not_null = if self.require { " not null" } else { "" };
414 match model {
415 "sqlite" => format!("`{}` time{} default '{}'", self.field, not_null, self.def),
416 "pgsql" => {
417 let sql = format!(r#""{}" time default '{}'"#, self.field, self.def);
418 format!(
419 "{} --{}|{}|{}|{}",
420 sql, self.title, self.mode, self.require, self.def
421 )
422 }
423 _ => {
424 let sql = format!("`{}` time{} default '{}'", self.field, not_null, self.def);
425 format!(
426 "{} comment '{}|{}|{}|{}'",
427 sql, self.title, self.mode, self.require, self.def
428 )
429 }
430 }
431 }
432 fn hide(&mut self) -> &mut Self {
433 self.show = false;
434 self
435 }
436
437 fn describe(&mut self, text: &str) -> &mut Self {
438 self.describe = text.to_string();
439 self
440 }
441
442 fn field(&mut self) -> JsonValue {
443 let mut field = object! {};
444 field
445 .insert("require", JsonValue::from(self.require))
446 .unwrap();
447 field
448 .insert("field", JsonValue::from(self.field.clone()))
449 .unwrap();
450 field
451 .insert("mode", JsonValue::from(self.mode.clone()))
452 .unwrap();
453 field
454 .insert("title", JsonValue::from(self.title.clone()))
455 .unwrap();
456 field
457 .insert("def", JsonValue::from(self.def.clone()))
458 .unwrap();
459
460 field.insert("show", JsonValue::from(self.show)).unwrap();
461 field
462 .insert("describe", JsonValue::from(self.describe.clone()))
463 .unwrap();
464 field.insert("example", self.example.clone()).unwrap();
465 field
466 }
467
468 fn swagger(&mut self) -> JsonValue {
469 object! {
470 "type": self.mode.clone(),
471 "example": self.example.clone(),
472 }
473 }
474 fn example(&mut self, data: JsonValue) -> &mut Self {
475 self.example = data.clone();
476 self
477 }
478}
479#[derive(Debug, Clone)]
480pub struct Date {
481 pub require: bool,
482 pub field: String,
483 pub mode: String,
484 pub title: String,
485 pub def: i64,
486 pub show: bool,
487 pub describe: String,
488 pub example: JsonValue,
489}
490
491impl Date {
492 pub fn new(require: bool, field: &str, title: &str, default: i64) -> Self {
493 Self {
494 field: field.to_string(),
495 mode: "date".to_string(),
496 title: title.to_string(),
497 def: default,
498 require,
499 show: true,
500 describe: "".to_string(),
501 example: JsonValue::Null,
502 }
503 }
504 pub fn date() -> i64 {
506 let now: DateTime<Local> = Local::now();
507 let today = now.format("%Y-%m-%d").to_string();
508 let t = NaiveDate::parse_from_str(&today, "%Y-%m-%d").unwrap();
509 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
510 t.and_hms_opt(0, 0, 0)
511 .unwrap()
512 .and_local_timezone(tz)
513 .unwrap()
514 .timestamp()
515 }
516 pub fn timestamp_to_date(timestamp: i64) -> String {
518 let d = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
519 let datetime = DateTime::<Local>::from(d);
520 let timestamp_str = datetime.format("%Y-%m-%d").to_string();
521 timestamp_str
522 }
523 pub fn date_to_timestamp(date: &str) -> i64 {
525 if date.is_empty() || date == "0001-01-01" {
526 return 0;
527 }
528 let t = NaiveDate::parse_from_str(date, "%Y-%m-%d");
529 match t {
530 Ok(d) => {
531 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
532 d.and_hms_opt(0, 0, 0)
533 .unwrap()
534 .and_local_timezone(tz)
535 .unwrap()
536 .timestamp()
537 }
538 Err(_) => 0,
539 }
540 }
541}
542
543impl Field for Date {
544 fn sql(&mut self, model: &str) -> String {
545 let not_null = if self.require { " not null" } else { "" };
546 let max = 10;
547 match model {
548 "sqlite" => {
549 format!("`{}` REAL{} default {}", self.field, not_null, self.def)
550 }
551 "pgsql" => {
552 let sql = format!(
553 r#""{}" decimal({},0) default {}"#,
554 self.field, max, self.def
555 );
556 format!(
557 "{} --{}|{}|{}|{}",
558 sql, self.title, self.mode, self.require, self.def
559 )
560 }
561 _ => {
562 let sql = format!(
563 "`{}` decimal({},0){} default {}",
564 self.field, max, not_null, self.def
565 );
566 format!(
567 "{} comment '{}|{}|{}|{}'",
568 sql, self.title, self.mode, self.require, self.def
569 )
570 }
571 }
572 }
573 fn hide(&mut self) -> &mut Self {
574 self.show = false;
575 self
576 }
577
578 fn describe(&mut self, text: &str) -> &mut Self {
579 self.describe = text.to_string();
580 self
581 }
582
583 fn field(&mut self) -> JsonValue {
584 let mut field = object! {};
585 field
586 .insert("require", JsonValue::from(self.require))
587 .unwrap();
588 field
589 .insert("field", JsonValue::from(self.field.clone()))
590 .unwrap();
591 field
592 .insert("mode", JsonValue::from(self.mode.clone()))
593 .unwrap();
594 field
595 .insert("title", JsonValue::from(self.title.clone()))
596 .unwrap();
597 field.insert("def", JsonValue::from(self.def)).unwrap();
598
599 field.insert("show", JsonValue::from(self.show)).unwrap();
600 field
601 .insert("describe", JsonValue::from(self.describe.clone()))
602 .unwrap();
603 field.insert("example", self.example.clone()).unwrap();
604 field
605 }
606 fn swagger(&mut self) -> JsonValue {
607 object! {
608 "type": self.mode.clone(),
609 "example": self.example.clone(),
610 }
611 }
612 fn example(&mut self, data: JsonValue) -> &mut Self {
613 self.example = data.clone();
614 self
615 }
616}
617#[derive(Debug, Clone)]
618pub struct Timestamp {
619 pub require: bool,
620 pub field: String,
621 pub mode: String,
622 pub title: String,
623 pub def: f64,
624 pub dec: i32,
625 pub show: bool,
626 pub describe: String,
627 pub example: JsonValue,
628}
629
630impl Timestamp {
631 pub fn new(require: bool, field: &str, title: &str, dec: i32, default: f64) -> Self {
632 Self {
633 require,
634 field: field.to_string(),
635 mode: "timestamp".to_string(),
636 title: title.to_string(),
637 def: default,
638 dec,
639 show: true,
640 describe: "".to_string(),
641 example: JsonValue::Null,
642 }
643 }
644 pub fn timestamp() -> i64 {
646 Local::now().timestamp()
647 }
648 pub fn timestamp_ms() -> i64 {
650 Local::now().timestamp_millis()
651 }
652 pub fn timestamp_ms_f64() -> f64 {
654 Local::now().timestamp_millis() as f64 / 1000.0
655 }
656 pub fn timestamp_μs() -> i64 {
658 Local::now().timestamp_micros()
659 }
660 pub fn timestamp_μs_f64() -> f64 {
662 Local::now().timestamp_micros() as f64 / 1000.0 / 1000.0
663 }
664 pub fn timestamp_ns() -> i64 {
666 Local::now().timestamp_nanos_opt().unwrap()
667 }
668
669 pub fn date_to_timestamp(date: &str) -> i64 {
671 let t = NaiveDate::parse_from_str(date, "%Y-%m-%d").unwrap();
672 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
673 t.and_hms_opt(0, 0, 0)
674 .unwrap()
675 .and_local_timezone(tz)
676 .unwrap()
677 .timestamp()
678 }
679 pub fn datetime_to_rfc2822(datetime: &str) -> String {
681 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
682 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
683 t.and_local_timezone(tz).unwrap().to_rfc2822()
684 }
685 pub fn datetime_utc_rfc2822(datetime: &str) -> String {
686 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
687 t.and_utc().to_rfc2822()
688 }
689 pub fn datetime_to_fmt(datetime: &str, fmt: &str) -> String {
690 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
691 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
692 t.and_local_timezone(tz).unwrap().format(fmt).to_string()
693 }
694 pub fn datetime_to_timestamp(datetime: &str, fmt: &str) -> i64 {
695 let t = NaiveDateTime::parse_from_str(datetime, fmt).unwrap();
696 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
697 t.and_local_timezone(tz).unwrap().timestamp()
698 }
699 pub fn datetime_timestamp(datetime: &str) -> i64 {
700 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
701 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
702 t.and_local_timezone(tz).unwrap().timestamp()
703 }
704}
705
706impl Field for Timestamp {
707 fn sql(&mut self, model: &str) -> String {
708 let not_null = if self.require { " not null" } else { "" };
709 let max = 10 + self.dec;
710 match model {
711 "sqlite" => {
712 let def = format!("{0:.width$}", self.def, width = self.dec as usize)
713 .parse::<f64>()
714 .unwrap();
715 format!("`{}` REAL{} default {}", self.field, not_null, def)
716 }
717 "pgsql" => {
718 let def = format!("{0:.width$}", self.def, width = self.dec as usize);
719 let def_value = def.parse::<f64>().unwrap();
720 let sql = format!(
721 r#""{}" decimal({},{}) default {}"#,
722 self.field, max, self.dec, def_value
723 );
724 format!(
725 "{} --{}|{}|{}|{}|{}",
726 sql, self.title, self.mode, self.require, self.dec, def_value
727 )
728 }
729 _ => {
730 let def = format!("{0:.width$}", self.def, width = self.dec as usize);
731 let def_value = def.parse::<f64>().unwrap();
732 let sql = format!(
733 "`{}` decimal({},{}){} default {}",
734 self.field, max, self.dec, not_null, def_value
735 );
736 format!(
737 "{} comment '{}|{}|{}|{}|{}'",
738 sql, self.title, self.mode, self.require, self.dec, def_value
739 )
740 }
741 }
742 }
743 fn hide(&mut self) -> &mut Self {
744 self.show = false;
745 self
746 }
747
748 fn describe(&mut self, text: &str) -> &mut Self {
749 self.describe = text.to_string();
750 self
751 }
752
753 fn field(&mut self) -> JsonValue {
754 let mut field = object! {};
755 field
756 .insert("require", JsonValue::from(self.require))
757 .unwrap();
758 field
759 .insert("field", JsonValue::from(self.field.clone()))
760 .unwrap();
761 field
762 .insert("mode", JsonValue::from(self.mode.clone()))
763 .unwrap();
764 field
765 .insert("title", JsonValue::from(self.title.clone()))
766 .unwrap();
767 field.insert("def", JsonValue::from(self.def)).unwrap();
768 field.insert("dec", JsonValue::from(self.dec)).unwrap();
769 field.insert("show", JsonValue::from(self.show)).unwrap();
770 field
771 .insert("describe", JsonValue::from(self.describe.clone()))
772 .unwrap();
773 field.insert("example", self.example.clone()).unwrap();
774 field
775 }
776
777 fn swagger(&mut self) -> JsonValue {
778 object! {
779 "type": self.mode.clone(),
780 "example": self.example.clone(),
781 }
782 }
783
784 fn example(&mut self, data: JsonValue) -> &mut Self {
785 self.example = data.clone();
786 self
787 }
788}