@@ -65,44 +65,63 @@ pub enum Item {
65
65
TimeZone ( time:: Offset ) ,
66
66
}
67
67
68
- fn expect_error ( input : & mut & str , reason : & ' static str ) ->ErrMode < ContextError > {
69
- ErrMode :: Cut ( ContextError :: new ( ) ) . add_context (
70
- input,
71
- & input. checkpoint ( ) ,
72
- StrContext :: Expected ( StrContextValue :: Description ( reason) ) ,
73
- )
68
+ /// Build a `DateTime<FixedOffset>` from a `DateTimeBuilder` and a base date.
69
+ pub ( crate ) fn at_date (
70
+ builder : DateTimeBuilder ,
71
+ base : DateTime < FixedOffset > ,
72
+ ) ->Result < DateTime < FixedOffset > , ParseDateTimeError > {
73
+ builder
74
+ . set_base ( base)
75
+ . build ( )
76
+ . ok_or ( ParseDateTimeError :: InvalidInput )
74
77
}
75
78
76
- /// Parse an item.
79
+ /// Build a `DateTime<FixedOffset>` from a `DateTimeBuilder` and the current
80
+ /// time.
81
+ pub ( crate ) fn at_local (
82
+ builder : DateTimeBuilder ,
83
+ ) ->Result < DateTime < FixedOffset > , ParseDateTimeError > {
84
+ builder. build ( ) . ok_or ( ParseDateTimeError :: InvalidInput )
85
+ }
86
+
87
+ /// Parse a date and time string.
77
88
///
78
89
/// Grammar:
79
90
///
80
91
/// ```ebnf
81
- /// item = combined | date | time | relative | weekday | timezone | year ;
92
+ /// spec = timestamp | items ;
93
+ ///
94
+ /// timestamp = "@" , dec_int ;
95
+ ///
96
+ /// items = item , { item } ;
97
+ /// item = datetime | date | time | relative | weekday | timezone | year ;
82
98
/// ```
83
- fn parse_item ( input : & mut & str ) ->ModalResult < Item > {
99
+ pub ( crate ) fn parse ( input : & mut & str ) ->ModalResult < DateTimeBuilder > {
100
+ trace ( "parse" , alt ( ( parse_timestamp, parse_items) ) ) . parse_next ( input)
101
+ }
102
+
103
+ /// Parse a timestamp.
104
+ ///
105
+ /// From the GNU docs:
106
+ ///
107
+ /// > (Timestamp) Such a number cannot be combined with any other date item, as
108
+ /// > it specifies a complete timestamp.
109
+ fn parse_timestamp ( input : & mut & str ) ->ModalResult < DateTimeBuilder > {
84
110
trace (
85
- "parse_item" ,
86
- alt ( (
87
- combined:: parse. map ( Item :: DateTime ) ,
88
- date:: parse. map ( Item :: Date ) ,
89
- time:: parse. map ( Item :: Time ) ,
90
- relative:: parse. map ( Item :: Relative ) ,
91
- weekday:: parse. map ( Item :: Weekday ) ,
92
- timezone:: parse. map ( Item :: TimeZone ) ,
93
- date:: year. map ( Item :: Year ) ,
94
- ) ) ,
111
+ "parse_timestamp" ,
112
+ terminated ( epoch:: parse. map ( Item :: Timestamp ) , eof) ,
95
113
)
114
+ . verify_map ( |ts : Item |{
115
+ if let Item :: Timestamp ( ts) = ts{
116
+ DateTimeBuilder :: new ( ) . set_timestamp ( ts) . ok ( )
117
+ } else {
118
+ None
119
+ }
120
+ } )
96
121
. parse_next ( input)
97
122
}
98
123
99
124
/// Parse a sequence of items.
100
- ///
101
- /// Grammar:
102
- ///
103
- /// ```ebnf
104
- /// items = item, { space, item } ;
105
- /// ```
106
125
fn parse_items ( input : & mut & str ) ->ModalResult < DateTimeBuilder > {
107
126
let mut builder =DateTimeBuilder :: new ( ) ;
108
127
@@ -157,52 +176,30 @@ fn parse_items(input: &mut &str) -> ModalResult<DateTimeBuilder> {
157
176
Ok ( builder)
158
177
}
159
178
160
- /// Parse a timestamp.
161
- ///
162
- /// From the GNU docs:
163
- ///
164
- /// (Timestamp) Such a number cannot be combined with any other date item, as it
165
- /// specifies a complete timestamp.
166
- fn parse_timestamp ( input : & mut & str ) ->ModalResult < DateTimeBuilder > {
179
+ /// Parse an item.
180
+ fn parse_item ( input : & mut & str ) ->ModalResult < Item > {
167
181
trace (
168
- "parse_timestamp" ,
169
- terminated ( epoch:: parse. map ( Item :: Timestamp ) , eof) ,
182
+ "parse_item" ,
183
+ alt ( (
184
+ combined:: parse. map ( Item :: DateTime ) ,
185
+ date:: parse. map ( Item :: Date ) ,
186
+ time:: parse. map ( Item :: Time ) ,
187
+ relative:: parse. map ( Item :: Relative ) ,
188
+ weekday:: parse. map ( Item :: Weekday ) ,
189
+ timezone:: parse. map ( Item :: TimeZone ) ,
190
+ date:: year. map ( Item :: Year ) ,
191
+ ) ) ,
170
192
)
171
- . verify_map ( |ts : Item |{
172
- if let Item :: Timestamp ( ts) = ts{
173
- DateTimeBuilder :: new ( ) . set_timestamp ( ts) . ok ( )
174
- } else {
175
- None
176
- }
177
- } )
178
193
. parse_next ( input)
179
194
}
180
195
181
- /// Parse a date and time string.
182
- ///
183
- /// Grammar:
184
- ///
185
- /// ```ebnf
186
- /// date_time = timestamp | items ;
187
- /// ```
188
- pub ( crate ) fn parse ( input : & mut & str ) ->ModalResult < DateTimeBuilder > {
189
- trace ( "parse" , alt ( ( parse_timestamp, parse_items) ) ) . parse_next ( input)
190
- }
191
-
192
- pub ( crate ) fn at_date (
193
- builder : DateTimeBuilder ,
194
- base : DateTime < FixedOffset > ,
195
- ) ->Result < DateTime < FixedOffset > , ParseDateTimeError > {
196
- builder
197
- . set_base ( base)
198
- . build ( )
199
- . ok_or ( ParseDateTimeError :: InvalidInput )
200
- }
201
-
202
- pub ( crate ) fn at_local (
203
- builder : DateTimeBuilder ,
204
- ) ->Result < DateTime < FixedOffset > , ParseDateTimeError > {
205
- builder. build ( ) . ok_or ( ParseDateTimeError :: InvalidInput )
196
+ /// Create an error with context for unexpected input.
197
+ fn expect_error ( input : & mut & str , reason : & ' static str ) ->ErrMode < ContextError > {
198
+ ErrMode :: Cut ( ContextError :: new ( ) ) . add_context (
199
+ input,
200
+ & input. checkpoint ( ) ,
201
+ StrContext :: Expected ( StrContextValue :: Description ( reason) ) ,
202
+ )
206
203
}
207
204
208
205
#[ cfg( test) ]