@@ -65,44 +65,63 @@ pub enum Item {
6565 TimeZone ( time:: Offset ) ,
6666}
6767
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 )
7477}
7578
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.
7788///
7889/// Grammar:
7990///
8091/// ```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 ;
8298/// ```
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 > {
84110 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) ,
95113 )
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+ } )
96121 . parse_next ( input)
97122}
98123
99124/// Parse a sequence of items.
100- ///
101- /// Grammar:
102- ///
103- /// ```ebnf
104- /// items = item, { space, item } ;
105- /// ```
106125fn parse_items ( input : & mut & str ) -> ModalResult < DateTimeBuilder > {
107126 let mut builder = DateTimeBuilder :: new ( ) ;
108127
@@ -157,52 +176,30 @@ fn parse_items(input: &mut &str) -> ModalResult<DateTimeBuilder> {
157176 Ok ( builder)
158177}
159178
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 > {
167181 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+ ) ) ,
170192 )
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- } )
178193 . parse_next ( input)
179194}
180195
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+ )
206203}
207204
208205#[ cfg( test) ]
0 commit comments