@@ -41,21 +41,21 @@ use super::{
41
41
} ;
42
42
43
43
#[ derive( PartialEq , Eq , Clone , Debug , Default ) ]
44
- pub struct Date {
45
- pub day : u32 ,
46
- pub month : u32 ,
47
- pub year : Option < u32 > ,
44
+ pub ( crate ) struct Date {
45
+ pub ( crate ) day : u8 ,
46
+ pub ( crate ) month : u8 ,
47
+ pub ( crate ) year : Option < u16 > ,
48
48
}
49
49
50
- impl TryFrom < ( & str , u32 , u32 ) > for Date {
50
+ impl TryFrom < ( & str , u8 , u8 ) > for Date {
51
51
type Error = & ' static str ;
52
52
53
53
/// Create a `Date` from a tuple of `(year, month, day)`.
54
54
///
55
55
/// Note: The `year` is represented as a `&str` to handle a specific GNU
56
56
/// compatibility quirk. See the comment in [`year`](super::year) for more
57
57
/// details.
58
- fn try_from ( value : ( & str , u32 , u32 ) ) -> Result < Self , Self :: Error > {
58
+ fn try_from ( value : ( & str , u8 , u8 ) ) -> Result < Self , Self :: Error > {
59
59
let ( year_str, month, day) = value;
60
60
let year = year_from_str ( year_str) ?;
61
61
@@ -80,11 +80,11 @@ impl TryFrom<(&str, u32, u32)> for Date {
80
80
}
81
81
}
82
82
83
- impl TryFrom < ( u32 , u32 ) > for Date {
83
+ impl TryFrom < ( u8 , u8 ) > for Date {
84
84
type Error = & ' static str ;
85
85
86
86
/// Create a `Date` from a tuple of `(month, day)`.
87
- fn try_from ( ( month, day) : ( u32 , u32 ) ) -> Result < Self , Self :: Error > {
87
+ fn try_from ( ( month, day) : ( u8 , u8 ) ) -> Result < Self , Self :: Error > {
88
88
if !( 1 ..=12 ) . contains ( & month) {
89
89
return Err ( "month must be between 1 and 12" ) ;
90
90
}
@@ -104,14 +104,27 @@ impl TryFrom<(u32, u32)> for Date {
104
104
}
105
105
}
106
106
107
- pub fn parse ( input : & mut & str ) -> ModalResult < Date > {
107
+ impl TryFrom < Date > for jiff:: civil:: Date {
108
+ type Error = & ' static str ;
109
+
110
+ fn try_from ( date : Date ) -> Result < Self , Self :: Error > {
111
+ jiff:: civil:: Date :: new (
112
+ date. year . unwrap_or ( 0 ) as i16 ,
113
+ date. month as i8 ,
114
+ date. day as i8 ,
115
+ )
116
+ . map_err ( |_| "date is not valid" )
117
+ }
118
+ }
119
+
120
+ pub ( super ) fn parse ( input : & mut & str ) -> ModalResult < Date > {
108
121
alt ( ( iso1, iso2, us, literal1, literal2) ) . parse_next ( input)
109
122
}
110
123
111
124
/// Parse `[year]-[month]-[day]`
112
125
///
113
126
/// This is also used by [`combined`](super::combined).
114
- pub fn iso1 ( input : & mut & str ) -> ModalResult < Date > {
127
+ pub ( super ) fn iso1 ( input : & mut & str ) -> ModalResult < Date > {
115
128
let ( year, _, month, _, day) =
116
129
( year_str, s ( '-' ) , s ( dec_uint) , s ( '-' ) , s ( dec_uint) ) . parse_next ( input) ?;
117
130
@@ -123,19 +136,13 @@ pub fn iso1(input: &mut &str) -> ModalResult<Date> {
123
136
/// Parse `[year][month][day]`
124
137
///
125
138
/// This is also used by [`combined`](super::combined).
126
- pub fn iso2 ( input : & mut & str ) -> ModalResult < Date > {
139
+ pub ( super ) fn iso2 ( input : & mut & str ) -> ModalResult < Date > {
127
140
let date_str = take_while ( 5 .., AsChar :: is_dec_digit) . parse_next ( input) ?;
128
141
let len = date_str. len ( ) ;
129
142
130
143
let year = & date_str[ ..len - 4 ] ;
131
-
132
- let month = date_str[ len - 4 ..len - 2 ]
133
- . parse :: < u32 > ( )
134
- . map_err ( |_| ErrMode :: Cut ( ctx_err ( "month must be a valid number" ) ) ) ?;
135
-
136
- let day = date_str[ len - 2 ..]
137
- . parse :: < u32 > ( )
138
- . map_err ( |_| ErrMode :: Cut ( ctx_err ( "day must be a valid number" ) ) ) ?;
144
+ let month = month_from_str ( & date_str[ len - 4 ..len - 2 ] ) ?;
145
+ let day = day_from_str ( & date_str[ len - 2 ..] ) ?;
139
146
140
147
( year, month, day)
141
148
. try_into ( )
@@ -158,27 +165,21 @@ fn us(input: &mut &str) -> ModalResult<Date> {
158
165
//
159
166
// GNU quirk: interpret as [year]/[month]/[day] if the first part is at
160
167
// least 4 characters long.
161
- let day = s2
162
- . parse :: < u32 > ( )
163
- . map_err ( |_| ErrMode :: Cut ( ctx_err ( "day must be a valid number" ) ) ) ?;
168
+ let day = day_from_str ( s2) ?;
164
169
( s1, n, day)
165
170
. try_into ( )
166
171
. map_err ( |e| ErrMode :: Cut ( ctx_err ( e) ) )
167
172
}
168
173
Some ( s2) => {
169
174
// [month]/[day]/[year]
170
- let month = s1
171
- . parse :: < u32 > ( )
172
- . map_err ( |_| ErrMode :: Cut ( ctx_err ( "month must be a valid number" ) ) ) ?;
175
+ let month = month_from_str ( s1) ?;
173
176
( s2, month, n)
174
177
. try_into ( )
175
178
. map_err ( |e| ErrMode :: Cut ( ctx_err ( e) ) )
176
179
}
177
180
None => {
178
181
// [month]/[day]
179
- let month = s1
180
- . parse :: < u32 > ( )
181
- . map_err ( |_| ErrMode :: Cut ( ctx_err ( "month must be a valid number" ) ) ) ?;
182
+ let month = month_from_str ( s1) ?;
182
183
( month, n) . try_into ( ) . map_err ( |e| ErrMode :: Cut ( ctx_err ( e) ) )
183
184
}
184
185
}
@@ -239,7 +240,7 @@ fn literal2(input: &mut &str) -> ModalResult<Date> {
239
240
}
240
241
241
242
/// Parse the name of a month (case-insensitive)
242
- fn literal_month ( input : & mut & str ) -> ModalResult < u32 > {
243
+ fn literal_month ( input : & mut & str ) -> ModalResult < u8 > {
243
244
s ( alpha1)
244
245
. verify_map ( |s : & str | {
245
246
Some ( match s {
@@ -261,6 +262,16 @@ fn literal_month(input: &mut &str) -> ModalResult<u32> {
261
262
. parse_next ( input)
262
263
}
263
264
265
+ fn month_from_str ( s : & str ) -> ModalResult < u8 > {
266
+ s. parse :: < u8 > ( )
267
+ . map_err ( |_| ErrMode :: Cut ( ctx_err ( "month must be a valid u8 number" ) ) )
268
+ }
269
+
270
+ fn day_from_str ( s : & str ) -> ModalResult < u8 > {
271
+ s. parse :: < u8 > ( )
272
+ . map_err ( |_| ErrMode :: Cut ( ctx_err ( "day must be a valid u8 number" ) ) )
273
+ }
274
+
264
275
#[ cfg( test) ]
265
276
mod tests {
266
277
use super :: { parse, Date } ;
0 commit comments