dailp/
date.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use serde::{Deserialize, Serialize};

/// Internal Date type which wraps a reliable date library.
/// Adds SQL and GraphQL support to the type.
#[derive(sqlx::Type, Serialize, Deserialize, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
#[sqlx(transparent)]
pub struct Date(pub chrono::NaiveDate);

impl Date {
    /// Make a new date from an underlying date object.
    pub fn new(internal: chrono::NaiveDate) -> Self {
        Self(internal)
    }
    /// Make a new date from year, month, and day integers.
    pub fn from_ymd(year: i32, month: u32, day: u32) -> Self {
        Self::new(
            chrono::NaiveDate::from_ymd_opt(year, month, day).expect("Provided date is invalid."),
        )
    }
    /// Parse a date from a string like "1999-12-31"
    pub fn parse(s: &str) -> Result<Self, chrono::ParseError> {
        chrono::NaiveDate::parse_from_str(s, "%Y-%m-%d").map(Self)
    }
}

#[async_graphql::Object]
impl Date {
    /// The year of this date
    pub async fn year(&self) -> i32 {
        use chrono::Datelike as _;
        self.0.year()
    }

    /// The month of this date
    pub async fn month(&self) -> u32 {
        use chrono::Datelike as _;
        self.0.month()
    }

    /// The day of this date
    pub async fn day(&self) -> u32 {
        use chrono::Datelike as _;
        self.0.day()
    }

    /// Formatted version of the date for humans to read
    pub async fn formatted_date(&self) -> String {
        self.0.format("%B %e, %Y").to_string()
    }
}
/// GraphQL input type for dates
#[derive(async_graphql::InputObject)]
pub struct DateInput {
    day: u32,
    month: u32,
    year: i32,
}

impl From<&DateInput> for Date {
    fn from(val: &DateInput) -> Self {
        Date::from_ymd(val.year, val.month, val.day)
    }
}

impl From<DateInput> for Date {
    fn from(di: DateInput) -> Self {
        Date::from_ymd(di.year, di.month, di.day)
    }
}

impl From<NaiveDate> for Date {
    fn from(nd: NaiveDate) -> Self {
        Date::new(nd)
    }
}

use chrono::{Datelike, NaiveDate};
impl DateInput {
    /// Creates a new DateInput from a day, month, and year.
    pub fn new(day: u32, month: u32, year: i32) -> Self {
        Self { day, month, year }
    }

    /// Creates a new DateInput from a Date object.
    pub fn parse_date_object(d: Date) -> Self {
        let nd = d.0;
        Self::new(nd.day(), nd.month(), nd.year())
    }
}

/// Internal DateTime type which wraps a reliable date library.
/// Adds SQL and GraphQL support to the type.
#[derive(sqlx::Type, Serialize, Deserialize, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
#[sqlx(transparent)]
pub struct DateTime(pub chrono::NaiveDateTime);

impl DateTime {
    /// Make a new date from an underlying date object.
    pub fn new(internal: chrono::NaiveDateTime) -> Self {
        Self(internal)
    }
}

#[async_graphql::Object]
impl DateTime {
    /// UNIX timestamp of the datetime, useful for sorting
    pub async fn timestamp(&self) -> i64 {
        self.0.and_utc().timestamp()
    }
    /// Just the Date component of this DateTime, useful for user-facing display
    pub async fn date(&self) -> Date {
        Date::new(self.0.date())
    }
}