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
360 .insert("def", JsonValue::from(self.def))
361 .unwrap();
362
363 field.insert("show", JsonValue::from(self.show)).unwrap();
364 field
365 .insert("describe", JsonValue::from(self.describe.clone()))
366 .unwrap();
367 field.insert("example", self.example.clone()).unwrap();
368 field
369 }
370
371 fn swagger(&mut self) -> JsonValue {
372 object! {
373 "type": self.mode.clone(),
374 "example": self.example.clone(),
375 }
376 }
377 fn example(&mut self, data: JsonValue) -> &mut Self {
378 self.example = data.clone();
379 self
380 }
381}
382#[derive(Debug, Clone)]
383pub struct Time {
384 pub require: bool,
385 pub field: String,
386 pub mode: String,
387 pub title: String,
388 pub def: String,
389 pub show: bool,
390 pub describe: String,
391 pub example: JsonValue,
392}
393
394impl Time {
395 pub fn new(require: bool, field: &str, title: &str, default: &str) -> Self {
396 Self {
397 field: field.to_string(),
398 mode: "time".to_string(),
399 title: title.to_string(),
400 def: default.to_string(),
401 require,
402 show: true,
403 describe: String::new(),
404 example: JsonValue::Null,
405 }
406 }
407 pub fn time() -> String {
408 let now: DateTime<Local> = Local::now();
409 let dft = now.format("%H:%M:%S");
410 dft.to_string()
411 }
412}
413
414impl Field for Time {
415 fn sql(&mut self, model: &str) -> String {
416 let not_null = if self.require { " not null" } else { "" };
417 match model {
418 "sqlite" => format!("`{}` time{} default '{}'", self.field, not_null, self.def),
419 "pgsql" => {
420 let sql = format!(r#""{}" time default '{}'"#, self.field, self.def);
421 format!(
422 "{} --{}|{}|{}|{}",
423 sql, self.title, self.mode, self.require, self.def
424 )
425 }
426 _ => {
427 let sql = format!("`{}` time{} default '{}'", self.field, not_null, self.def);
428 format!(
429 "{} comment '{}|{}|{}|{}'",
430 sql, self.title, self.mode, self.require, self.def
431 )
432 }
433 }
434 }
435 fn hide(&mut self) -> &mut Self {
436 self.show = false;
437 self
438 }
439
440 fn describe(&mut self, text: &str) -> &mut Self {
441 self.describe = text.to_string();
442 self
443 }
444
445 fn field(&mut self) -> JsonValue {
446 let mut field = object! {};
447 field
448 .insert("require", JsonValue::from(self.require))
449 .unwrap();
450 field
451 .insert("field", JsonValue::from(self.field.clone()))
452 .unwrap();
453 field
454 .insert("mode", JsonValue::from(self.mode.clone()))
455 .unwrap();
456 field
457 .insert("title", JsonValue::from(self.title.clone()))
458 .unwrap();
459 field
460 .insert("def", JsonValue::from(self.def.clone()))
461 .unwrap();
462
463 field.insert("show", JsonValue::from(self.show)).unwrap();
464 field
465 .insert("describe", JsonValue::from(self.describe.clone()))
466 .unwrap();
467 field.insert("example", self.example.clone()).unwrap();
468 field
469 }
470
471 fn swagger(&mut self) -> JsonValue {
472 object! {
473 "type": self.mode.clone(),
474 "example": self.example.clone(),
475 }
476 }
477 fn example(&mut self, data: JsonValue) -> &mut Self {
478 self.example = data.clone();
479 self
480 }
481}
482#[derive(Debug, Clone)]
483pub struct Date {
484 pub require: bool,
485 pub field: String,
486 pub mode: String,
487 pub title: String,
488 pub def: i64,
489 pub show: bool,
490 pub describe: String,
491 pub example: JsonValue,
492}
493
494impl Date {
495 pub fn new(require: bool, field: &str, title: &str, default: i64) -> Self {
496 Self {
497 field: field.to_string(),
498 mode: "date".to_string(),
499 title: title.to_string(),
500 def: default,
501 require,
502 show: true,
503 describe: "".to_string(),
504 example: JsonValue::Null,
505 }
506 }
507 pub fn date() -> i64 {
509 let now: DateTime<Local> = Local::now();
510 let today = now.format("%Y-%m-%d").to_string();
511 let t = NaiveDate::parse_from_str(&today, "%Y-%m-%d").unwrap();
512 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
513 t.and_hms_opt(0, 0, 0)
514 .unwrap()
515 .and_local_timezone(tz)
516 .unwrap()
517 .timestamp()
518 }
519 pub fn timestamp_to_date(timestamp: i64) -> String {
521 let d = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
522 let datetime = DateTime::<Local>::from(d);
523 let timestamp_str = datetime.format("%Y-%m-%d").to_string();
524 timestamp_str
525 }
526 pub fn date_to_timestamp(date: &str) -> i64 {
528 if date.is_empty() || date == "0001-01-01" {
529 return 0;
530 }
531 let t = NaiveDate::parse_from_str(date, "%Y-%m-%d");
532 match t {
533 Ok(d) => {
534 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
535 d.and_hms_opt(0, 0, 0)
536 .unwrap()
537 .and_local_timezone(tz)
538 .unwrap()
539 .timestamp()
540 }
541 Err(_) => 0,
542 }
543 }
544}
545
546impl Field for Date {
547 fn sql(&mut self, model: &str) -> String {
548 let not_null = if self.require { " not null" } else { "" };
549 let max = 10;
550 match model {
551 "sqlite" => {
552 format!("`{}` REAL{} default {}", self.field, not_null, self.def)
553 }
554 "pgsql" => {
555 let sql = format!(
556 r#""{}" decimal({},0) default {}"#,
557 self.field, max, self.def
558 );
559 format!(
560 "{} --{}|{}|{}|{}",
561 sql, self.title, self.mode, self.require, self.def
562 )
563 }
564 _ => {
565 let sql = format!(
566 "`{}` decimal({},0){} default {}",
567 self.field, max, not_null, self.def
568 );
569 format!(
570 "{} comment '{}|{}|{}|{}'",
571 sql, self.title, self.mode, self.require, self.def
572 )
573 }
574 }
575 }
576 fn hide(&mut self) -> &mut Self {
577 self.show = false;
578 self
579 }
580
581 fn describe(&mut self, text: &str) -> &mut Self {
582 self.describe = text.to_string();
583 self
584 }
585
586 fn field(&mut self) -> JsonValue {
587 let mut field = object! {};
588 field
589 .insert("require", JsonValue::from(self.require))
590 .unwrap();
591 field
592 .insert("field", JsonValue::from(self.field.clone()))
593 .unwrap();
594 field
595 .insert("mode", JsonValue::from(self.mode.clone()))
596 .unwrap();
597 field
598 .insert("title", JsonValue::from(self.title.clone()))
599 .unwrap();
600 field.insert("def", JsonValue::from(self.def)).unwrap();
601
602 field.insert("show", JsonValue::from(self.show)).unwrap();
603 field
604 .insert("describe", JsonValue::from(self.describe.clone()))
605 .unwrap();
606 field.insert("example", self.example.clone()).unwrap();
607 field
608 }
609 fn swagger(&mut self) -> JsonValue {
610 object! {
611 "type": self.mode.clone(),
612 "example": self.example.clone(),
613 }
614 }
615 fn example(&mut self, data: JsonValue) -> &mut Self {
616 self.example = data.clone();
617 self
618 }
619}
620#[derive(Debug, Clone)]
621pub struct Timestamp {
622 pub require: bool,
623 pub field: String,
624 pub mode: String,
625 pub title: String,
626 pub def: f64,
627 pub dec: i32,
628 pub show: bool,
629 pub describe: String,
630 pub example: JsonValue,
631}
632
633impl Timestamp {
634 pub fn new(require: bool, field: &str, title: &str, dec: i32, default: f64) -> Self {
635 Self {
636 require,
637 field: field.to_string(),
638 mode: "timestamp".to_string(),
639 title: title.to_string(),
640 def: default,
641 dec,
642 show: true,
643 describe: "".to_string(),
644 example: JsonValue::Null,
645 }
646 }
647 pub fn timestamp() -> i64 {
649 Local::now().timestamp()
650 }
651 pub fn timestamp_ms() -> i64 {
653 Local::now().timestamp_millis()
654 }
655 pub fn timestamp_ms_f64() -> f64 {
657 Local::now().timestamp_millis() as f64 / 1000.0
658 }
659 pub fn timestamp_μs() -> i64 {
661 Local::now().timestamp_micros()
662 }
663 pub fn timestamp_μs_f64() -> f64 {
665 Local::now().timestamp_micros() as f64 / 1000.0 / 1000.0
666 }
667 pub fn timestamp_ns() -> i64 {
669 Local::now().timestamp_nanos_opt().unwrap()
670 }
671
672 pub fn date_to_timestamp(date: &str) -> i64 {
674 let t = NaiveDate::parse_from_str(date, "%Y-%m-%d").unwrap();
675 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
676 t.and_hms_opt(0, 0, 0)
677 .unwrap()
678 .and_local_timezone(tz)
679 .unwrap()
680 .timestamp()
681 }
682 pub fn datetime_to_rfc2822(datetime: &str) -> String {
684 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
685 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
686 t.and_local_timezone(tz).unwrap().to_rfc2822()
687 }
688 pub fn datetime_utc_rfc2822(datetime: &str) -> String {
689 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
690 t.and_utc().to_rfc2822()
691 }
692 pub fn datetime_to_fmt(datetime: &str, fmt: &str) -> String {
693 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
694 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
695 t.and_local_timezone(tz).unwrap().format(fmt).to_string()
696 }
697 pub fn datetime_to_timestamp(datetime: &str, fmt: &str) -> i64 {
698 let t = NaiveDateTime::parse_from_str(datetime, fmt).unwrap();
699 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
700 t.and_local_timezone(tz).unwrap().timestamp()
701 }
702 pub fn datetime_timestamp(datetime: &str) -> i64 {
703 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
704 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
705 t.and_local_timezone(tz).unwrap().timestamp()
706 }
707}
708
709impl Field for Timestamp {
710 fn sql(&mut self, model: &str) -> String {
711 let not_null = if self.require { " not null" } else { "" };
712 let max = 10 + self.dec;
713 match model {
714 "sqlite" => {
715 let def = format!("{0:.width$}", self.def, width = self.dec as usize)
716 .parse::<f64>()
717 .unwrap();
718 format!("`{}` REAL{} default {}", self.field, not_null, def)
719 }
720 "pgsql" => {
721 let def = format!("{0:.width$}", self.def, width = self.dec as usize);
722 let def_value = def.parse::<f64>().unwrap();
723 let sql = format!(
724 r#""{}" decimal({},{}) default {}"#,
725 self.field, max, self.dec, def_value
726 );
727 format!(
728 "{} --{}|{}|{}|{}|{}",
729 sql, self.title, self.mode, self.require, self.dec, def_value
730 )
731 }
732 _ => {
733 let def = format!("{0:.width$}", self.def, width = self.dec as usize);
734 let def_value = def.parse::<f64>().unwrap();
735 let sql = format!(
736 "`{}` decimal({},{}){} default {}",
737 self.field, max, self.dec, not_null, def_value
738 );
739 format!(
740 "{} comment '{}|{}|{}|{}|{}'",
741 sql, self.title, self.mode, self.require, self.dec, def_value
742 )
743 }
744 }
745 }
746 fn hide(&mut self) -> &mut Self {
747 self.show = false;
748 self
749 }
750
751 fn describe(&mut self, text: &str) -> &mut Self {
752 self.describe = text.to_string();
753 self
754 }
755
756 fn field(&mut self) -> JsonValue {
757 let mut field = object! {};
758 field
759 .insert("require", JsonValue::from(self.require))
760 .unwrap();
761 field
762 .insert("field", JsonValue::from(self.field.clone()))
763 .unwrap();
764 field
765 .insert("mode", JsonValue::from(self.mode.clone()))
766 .unwrap();
767 field
768 .insert("title", JsonValue::from(self.title.clone()))
769 .unwrap();
770 field.insert("def", JsonValue::from(self.def)).unwrap();
771 field.insert("dec", JsonValue::from(self.dec)).unwrap();
772 field.insert("show", JsonValue::from(self.show)).unwrap();
773 field
774 .insert("describe", JsonValue::from(self.describe.clone()))
775 .unwrap();
776 field.insert("example", self.example.clone()).unwrap();
777 field
778 }
779
780 fn swagger(&mut self) -> JsonValue {
781 object! {
782 "type": self.mode.clone(),
783 "example": self.example.clone(),
784 }
785 }
786
787 fn example(&mut self, data: JsonValue) -> &mut Self {
788 self.example = data.clone();
789 self
790 }
791}