Skip to main content

br_fields/
datetime.rs

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
114/// 年月 (时间戳存储)
115///
116/// * require 是否必填
117/// * field 字段名
118/// * mode 模式 yearmonth
119/// * title 字段描述
120/// * def 默认值 (时间戳,存储为每月1日 00:00:00)
121pub 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    /// 获取当前年月时间戳 (每月1日 00:00:00)
146    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    /// YYYY-MM 格式转时间戳
155    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    /// 时间戳转 YYYY-MM 格式
166    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    /// 默认值 2023-01-01
499    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    /// 默认值 秒 10位
607    pub fn timestamp() -> i64 {
608        Local::now().timestamp()
609    }
610    /// 毫秒 13位
611    pub fn timestamp_ms() -> i64 {
612        Local::now().timestamp_millis()
613    }
614    /// 毫秒 10位+3位
615    pub fn timestamp_ms_f64() -> f64 {
616        Local::now().timestamp_millis() as f64 / 1000.0
617    }
618    /// 微秒 16位
619    pub fn timestamp_μs() -> i64 {
620        Local::now().timestamp_micros()
621    }
622    /// 微秒 16位
623    pub fn timestamp_μs_f64() -> f64 {
624        Local::now().timestamp_micros() as f64 / 1000.0 / 1000.0
625    }
626    /// 纳秒 19位
627    pub fn timestamp_ns() -> i64 {
628        Local::now().timestamp_nanos_opt().unwrap()
629    }
630
631    /// 日期转时间戳
632    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    /// 日期时间转rfc2822 Thu, 3 Jul 2014 17:43:58 +0000
642    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}