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
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 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: 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!(
298 "`{}` datetime{} default '{}'",
299 self.field, not_null, self.def
300 ),
301 "pgsql" => {
302 let sql = format!(r#""{}" timestamp default '{}'"#, self.field, self.def);
303 format!(
304 "{} --{}|{}|{}|{}",
305 sql, self.title, self.mode, self.require, self.def
306 )
307 }
308 _ => {
309 let sql = format!(
310 "`{}` datetime{} default '{}'",
311 self.field, not_null, self.def
312 );
313 format!(
314 "{} comment '{}|{}|{}|{}'",
315 sql, self.title, self.mode, self.require, 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 let sql = format!(r#""{}" time default '{}'"#, self.field, self.def);
405 format!(
406 "{} --{}|{}|{}|{}",
407 sql, self.title, self.mode, self.require, self.def
408 )
409 }
410 _ => {
411 let sql = format!("`{}` time{} default '{}'", self.field, not_null, self.def);
412 format!(
413 "{} comment '{}|{}|{}|{}'",
414 sql, self.title, self.mode, self.require, self.def
415 )
416 }
417 }
418 }
419 fn hide(&mut self) -> &mut Self {
420 self.show = false;
421 self
422 }
423
424 fn describe(&mut self, text: &str) -> &mut Self {
425 self.describe = text.to_string();
426 self
427 }
428
429 fn field(&mut self) -> JsonValue {
430 let mut field = object! {};
431 field
432 .insert("require", JsonValue::from(self.require))
433 .unwrap();
434 field
435 .insert("field", JsonValue::from(self.field.clone()))
436 .unwrap();
437 field
438 .insert("mode", JsonValue::from(self.mode.clone()))
439 .unwrap();
440 field
441 .insert("title", JsonValue::from(self.title.clone()))
442 .unwrap();
443 field
444 .insert("def", JsonValue::from(self.def.clone()))
445 .unwrap();
446
447 field.insert("show", JsonValue::from(self.show)).unwrap();
448 field
449 .insert("describe", JsonValue::from(self.describe.clone()))
450 .unwrap();
451 field.insert("example", self.example.clone()).unwrap();
452 field
453 }
454
455 fn swagger(&mut self) -> JsonValue {
456 object! {
457 "type": self.mode.clone(),
458 "example": self.example.clone(),
459 }
460 }
461 fn example(&mut self, data: JsonValue) -> &mut Self {
462 self.example = data.clone();
463 self
464 }
465}
466#[derive(Debug, Clone)]
467pub struct Date {
468 pub require: bool,
469 pub field: String,
470 pub mode: String,
471 pub title: String,
472 pub def: String,
473 pub show: bool,
474 pub describe: String,
475 pub example: JsonValue,
476}
477
478impl Date {
479 pub fn new(require: bool, field: &str, title: &str, default: &str) -> Self {
480 let def = {
481 if default.is_empty() {
482 "0001-01-01"
483 } else {
484 default
485 }
486 };
487 Self {
488 field: field.to_string(),
489 mode: "date".to_string(),
490 title: title.to_string(),
491 def: def.parse().unwrap(),
492 require,
493 show: true,
494 describe: "".to_string(),
495 example: JsonValue::Null,
496 }
497 }
498 pub fn date() -> String {
500 let now: DateTime<Local> = Local::now();
501 let dft = now.format("%Y-%m-%d");
502 dft.to_string()
503 }
504 pub fn timestamp_to_date(timestamp: i64) -> String {
505 let d = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
506 let datetime = DateTime::<Local>::from(d);
507 let timestamp_str = datetime.format("%Y-%m-%d").to_string();
508 timestamp_str
509 }
510}
511
512impl Field for Date {
513 fn sql(&mut self, model: &str) -> String {
514 let not_null = if self.require { " not null" } else { "" };
515 match model {
516 "sqlite" => format!("`{}` date{} default '{}'", self.field, not_null, self.def),
517 "pgsql" => {
518 let sql = format!(r#""{}" date default '{}'"#, self.field, self.def);
519 format!(
520 "{} --{}|{}|{}|{}",
521 sql, self.title, self.mode, self.require, self.def
522 )
523 }
524 _ => {
525 let sql = format!("`{}` date{} default '{}'", self.field, not_null, self.def);
526 format!(
527 "{} comment '{}|{}|{}|{}'",
528 sql, self.title, self.mode, self.require, self.def
529 )
530 }
531 }
532 }
533 fn hide(&mut self) -> &mut Self {
534 self.show = false;
535 self
536 }
537
538 fn describe(&mut self, text: &str) -> &mut Self {
539 self.describe = text.to_string();
540 self
541 }
542
543 fn field(&mut self) -> JsonValue {
544 let mut field = object! {};
545 field
546 .insert("require", JsonValue::from(self.require))
547 .unwrap();
548 field
549 .insert("field", JsonValue::from(self.field.clone()))
550 .unwrap();
551 field
552 .insert("mode", JsonValue::from(self.mode.clone()))
553 .unwrap();
554 field
555 .insert("title", JsonValue::from(self.title.clone()))
556 .unwrap();
557 field
558 .insert("def", JsonValue::from(self.def.clone()))
559 .unwrap();
560
561 field.insert("show", JsonValue::from(self.show)).unwrap();
562 field
563 .insert("describe", JsonValue::from(self.describe.clone()))
564 .unwrap();
565 field.insert("example", self.example.clone()).unwrap();
566 field
567 }
568 fn swagger(&mut self) -> JsonValue {
569 object! {
570 "type": self.mode.clone(),
571 "example": self.example.clone(),
572 }
573 }
574 fn example(&mut self, data: JsonValue) -> &mut Self {
575 self.example = data.clone();
576 self
577 }
578}
579#[derive(Debug, Clone)]
580pub struct Timestamp {
581 pub require: bool,
582 pub field: String,
583 pub mode: String,
584 pub title: String,
585 pub def: f64,
586 pub dec: i32,
587 pub show: bool,
588 pub describe: String,
589 pub example: JsonValue,
590}
591
592impl Timestamp {
593 pub fn new(require: bool, field: &str, title: &str, dec: i32, default: f64) -> Self {
594 Self {
595 require,
596 field: field.to_string(),
597 mode: "timestamp".to_string(),
598 title: title.to_string(),
599 def: default,
600 dec,
601 show: true,
602 describe: "".to_string(),
603 example: JsonValue::Null,
604 }
605 }
606 pub fn timestamp() -> i64 {
608 Local::now().timestamp()
609 }
610 pub fn timestamp_ms() -> i64 {
612 Local::now().timestamp_millis()
613 }
614 pub fn timestamp_ms_f64() -> f64 {
616 Local::now().timestamp_millis() as f64 / 1000.0
617 }
618 pub fn timestamp_μs() -> i64 {
620 Local::now().timestamp_micros()
621 }
622 pub fn timestamp_μs_f64() -> f64 {
624 Local::now().timestamp_micros() as f64 / 1000.0 / 1000.0
625 }
626 pub fn timestamp_ns() -> i64 {
628 Local::now().timestamp_nanos_opt().unwrap()
629 }
630
631 pub fn date_to_timestamp(date: &str) -> i64 {
633 let t = NaiveDate::parse_from_str(date, "%Y-%m-%d").unwrap();
634 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
635 t.and_hms_opt(0, 0, 0)
636 .unwrap()
637 .and_local_timezone(tz)
638 .unwrap()
639 .timestamp()
640 }
641 pub fn datetime_to_rfc2822(datetime: &str) -> String {
643 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
644 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
645 t.and_local_timezone(tz).unwrap().to_rfc2822()
646 }
647 pub fn datetime_utc_rfc2822(datetime: &str) -> String {
648 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
649 t.and_utc().to_rfc2822()
650 }
651 pub fn datetime_to_fmt(datetime: &str, fmt: &str) -> String {
652 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
653 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
654 t.and_local_timezone(tz).unwrap().format(fmt).to_string()
655 }
656 pub fn datetime_to_timestamp(datetime: &str, fmt: &str) -> i64 {
657 let t = NaiveDateTime::parse_from_str(datetime, fmt).unwrap();
658 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
659 t.and_local_timezone(tz).unwrap().timestamp()
660 }
661 pub fn datetime_timestamp(datetime: &str) -> i64 {
662 let t = NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").unwrap();
663 let tz = FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap();
664 t.and_local_timezone(tz).unwrap().timestamp()
665 }
666}
667
668impl Field for Timestamp {
669 fn sql(&mut self, model: &str) -> String {
670 let not_null = if self.require { " not null" } else { "" };
671 let max = 10 + self.dec;
672 match model {
673 "sqlite" => {
674 let def = format!("{0:.width$}", self.def, width = self.dec as usize)
675 .parse::<f64>()
676 .unwrap();
677 format!("`{}` REAL{} default {}", self.field, not_null, def)
678 }
679 "pgsql" => {
680 let def = format!("{0:.width$}", self.def, width = self.dec as usize);
681 let def_value = def.parse::<f64>().unwrap();
682 let sql = format!(
683 r#""{}" decimal({},{}) default {}"#,
684 self.field, max, self.dec, def_value
685 );
686 format!(
687 "{} --{}|{}|{}|{}|{}",
688 sql, self.title, self.mode, self.require, self.dec, def_value
689 )
690 }
691 _ => {
692 let def = format!("{0:.width$}", self.def, width = self.dec as usize);
693 let def_value = def.parse::<f64>().unwrap();
694 let sql = format!(
695 "`{}` decimal({},{}){} default {}",
696 self.field, max, self.dec, not_null, def_value
697 );
698 format!(
699 "{} comment '{}|{}|{}|{}|{}'",
700 sql, self.title, self.mode, self.require, self.dec, def_value
701 )
702 }
703 }
704 }
705 fn hide(&mut self) -> &mut Self {
706 self.show = false;
707 self
708 }
709
710 fn describe(&mut self, text: &str) -> &mut Self {
711 self.describe = text.to_string();
712 self
713 }
714
715 fn field(&mut self) -> JsonValue {
716 let mut field = object! {};
717 field
718 .insert("require", JsonValue::from(self.require))
719 .unwrap();
720 field
721 .insert("field", JsonValue::from(self.field.clone()))
722 .unwrap();
723 field
724 .insert("mode", JsonValue::from(self.mode.clone()))
725 .unwrap();
726 field
727 .insert("title", JsonValue::from(self.title.clone()))
728 .unwrap();
729 field.insert("def", JsonValue::from(self.def)).unwrap();
730 field.insert("dec", JsonValue::from(self.dec)).unwrap();
731 field.insert("show", JsonValue::from(self.show)).unwrap();
732 field
733 .insert("describe", JsonValue::from(self.describe.clone()))
734 .unwrap();
735 field.insert("example", self.example.clone()).unwrap();
736 field
737 }
738
739 fn swagger(&mut self) -> JsonValue {
740 object! {
741 "type": self.mode.clone(),
742 "example": self.example.clone(),
743 }
744 }
745
746 fn example(&mut self, data: JsonValue) -> &mut Self {
747 self.example = data.clone();
748 self
749 }
750}