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