@@ -14,7 +14,7 @@ use crate::format_description::well_known::{Iso8601, Rfc2822, Rfc3339};
1414use crate :: internal_macros:: bug;
1515use crate :: parsing:: combinator:: { Sign , one_or_two_digits} ;
1616use crate :: parsing:: { Parsed , ParsedItem } ;
17- use crate :: { Date , Month , OffsetDateTime , Time , UtcOffset , Weekday , error} ;
17+ use crate :: { Date , Month , OffsetDateTime , Time , UtcOffset , error} ;
1818
1919/// A type that can be parsed.
2020#[ cfg_attr( docsrs, doc( notable_trait) ) ]
@@ -172,25 +172,23 @@ impl sealed::Sealed for Rfc2822 {
172172 parsed : & mut Parsed ,
173173 ) -> Result < & ' a [ u8 ] , error:: Parse > {
174174 use crate :: error:: ParseFromDescription :: { InvalidComponent , InvalidLiteral } ;
175- use crate :: parsing:: combinator:: rfc:: rfc2822:: { cfws, fws} ;
176- use crate :: parsing:: combinator:: { ExactlyNDigits , ascii_char, first_match, opt, sign} ;
175+ use crate :: format_description:: modifier;
176+ use crate :: parsing:: combinator:: rfc:: rfc2822:: { cfws, fws, zone_literal} ;
177+ use crate :: parsing:: combinator:: { ExactlyNDigits , ascii_char, opt, sign} ;
178+ use crate :: parsing:: component;
177179
178180 let colon = ascii_char :: < b':' > ;
179181 let comma = ascii_char :: < b',' > ;
180182
181183 let input = opt ( cfws) ( input) . into_inner ( ) ;
182- let weekday = first_match (
183- [
184- ( b"Mon" . as_slice ( ) , Weekday :: Monday ) ,
185- ( b"Tue" . as_slice ( ) , Weekday :: Tuesday ) ,
186- ( b"Wed" . as_slice ( ) , Weekday :: Wednesday ) ,
187- ( b"Thu" . as_slice ( ) , Weekday :: Thursday ) ,
188- ( b"Fri" . as_slice ( ) , Weekday :: Friday ) ,
189- ( b"Sat" . as_slice ( ) , Weekday :: Saturday ) ,
190- ( b"Sun" . as_slice ( ) , Weekday :: Sunday ) ,
191- ] ,
192- false ,
193- ) ( input) ;
184+ let weekday = component:: parse_weekday (
185+ input,
186+ modifier:: Weekday {
187+ repr : modifier:: WeekdayRepr :: Short ,
188+ one_indexed : false ,
189+ case_sensitive : false ,
190+ } ,
191+ ) ;
194192 let input = if let Some ( item) = weekday {
195193 let input = item
196194 . consume_value ( |value| parsed. set_weekday ( value) )
@@ -204,23 +202,14 @@ impl sealed::Sealed for Rfc2822 {
204202 . and_then ( |item| item. consume_value ( |value| parsed. set_day ( NonZero :: new ( value) ?) ) )
205203 . ok_or ( InvalidComponent ( "day" ) ) ?;
206204 let input = cfws ( input) . ok_or ( InvalidLiteral ) ?. into_inner ( ) ;
207- let input = first_match (
208- [
209- ( b"Jan" . as_slice ( ) , Month :: January ) ,
210- ( b"Feb" . as_slice ( ) , Month :: February ) ,
211- ( b"Mar" . as_slice ( ) , Month :: March ) ,
212- ( b"Apr" . as_slice ( ) , Month :: April ) ,
213- ( b"May" . as_slice ( ) , Month :: May ) ,
214- ( b"Jun" . as_slice ( ) , Month :: June ) ,
215- ( b"Jul" . as_slice ( ) , Month :: July ) ,
216- ( b"Aug" . as_slice ( ) , Month :: August ) ,
217- ( b"Sep" . as_slice ( ) , Month :: September ) ,
218- ( b"Oct" . as_slice ( ) , Month :: October ) ,
219- ( b"Nov" . as_slice ( ) , Month :: November ) ,
220- ( b"Dec" . as_slice ( ) , Month :: December ) ,
221- ] ,
222- false ,
223- ) ( input)
205+ let input = component:: parse_month (
206+ input,
207+ modifier:: Month {
208+ padding : modifier:: Padding :: None ,
209+ repr : modifier:: MonthRepr :: Short ,
210+ case_sensitive : false ,
211+ } ,
212+ )
224213 . and_then ( |item| item. consume_value ( |value| parsed. set_month ( value) ) )
225214 . ok_or ( InvalidComponent ( "month" ) ) ?;
226215 let input = cfws ( input) . ok_or ( InvalidLiteral ) ?. into_inner ( ) ;
@@ -271,33 +260,7 @@ impl sealed::Sealed for Rfc2822 {
271260 // The RFC explicitly allows leap seconds.
272261 parsed. leap_second_allowed = true ;
273262
274- #[ expect(
275- clippy:: unnecessary_lazy_evaluations,
276- reason = "rust-lang/rust-clippy#8522"
277- ) ]
278- let zone_literal = first_match (
279- [
280- ( b"UT" . as_slice ( ) , 0 ) ,
281- ( b"GMT" . as_slice ( ) , 0 ) ,
282- ( b"EST" . as_slice ( ) , -5 ) ,
283- ( b"EDT" . as_slice ( ) , -4 ) ,
284- ( b"CST" . as_slice ( ) , -6 ) ,
285- ( b"CDT" . as_slice ( ) , -5 ) ,
286- ( b"MST" . as_slice ( ) , -7 ) ,
287- ( b"MDT" . as_slice ( ) , -6 ) ,
288- ( b"PST" . as_slice ( ) , -8 ) ,
289- ( b"PDT" . as_slice ( ) , -7 ) ,
290- ] ,
291- false ,
292- ) ( input)
293- . or_else ( || match input {
294- [
295- b'a' ..=b'i' | b'k' ..=b'z' | b'A' ..=b'I' | b'K' ..=b'Z' ,
296- rest @ ..,
297- ] => Some ( ParsedItem ( rest, 0 ) ) ,
298- _ => None ,
299- } ) ;
300- if let Some ( zone_literal) = zone_literal {
263+ if let Some ( zone_literal) = zone_literal ( input) {
301264 let input = zone_literal
302265 . consume_value ( |value| parsed. set_offset_hour ( value) )
303266 . ok_or ( InvalidComponent ( "offset hour" ) ) ?;
@@ -333,53 +296,40 @@ impl sealed::Sealed for Rfc2822 {
333296
334297 fn parse_offset_date_time ( & self , input : & [ u8 ] ) -> Result < OffsetDateTime , error:: Parse > {
335298 use crate :: error:: ParseFromDescription :: { InvalidComponent , InvalidLiteral } ;
336- use crate :: parsing:: combinator:: rfc:: rfc2822:: { cfws, fws} ;
337- use crate :: parsing:: combinator:: { ExactlyNDigits , ascii_char, first_match, opt, sign} ;
299+ use crate :: format_description:: modifier;
300+ use crate :: parsing:: combinator:: rfc:: rfc2822:: { cfws, fws, zone_literal} ;
301+ use crate :: parsing:: combinator:: { ExactlyNDigits , ascii_char, opt, sign} ;
302+ use crate :: parsing:: component;
338303
339304 let colon = ascii_char :: < b':' > ;
340305 let comma = ascii_char :: < b',' > ;
341306
342307 let input = opt ( cfws) ( input) . into_inner ( ) ;
343- // This parses the weekday, but we don't actually use the value anywhere. Because of this,
344- // just return `()` to avoid unnecessary generated code.
345- let weekday = first_match (
346- [
347- ( b"Mon" . as_slice ( ) , ( ) ) ,
348- ( b"Tue" . as_slice ( ) , ( ) ) ,
349- ( b"Wed" . as_slice ( ) , ( ) ) ,
350- ( b"Thu" . as_slice ( ) , ( ) ) ,
351- ( b"Fri" . as_slice ( ) , ( ) ) ,
352- ( b"Sat" . as_slice ( ) , ( ) ) ,
353- ( b"Sun" . as_slice ( ) , ( ) ) ,
354- ] ,
355- false ,
356- ) ( input) ;
308+ let weekday = component:: parse_weekday (
309+ input,
310+ modifier:: Weekday {
311+ repr : modifier:: WeekdayRepr :: Short ,
312+ one_indexed : false ,
313+ case_sensitive : false ,
314+ } ,
315+ ) ;
357316 let input = if let Some ( item) = weekday {
358- let input = item. into_inner ( ) ;
317+ let input = item. discard_value ( ) ;
359318 let input = comma ( input) . ok_or ( InvalidLiteral ) ?. into_inner ( ) ;
360319 opt ( cfws) ( input) . into_inner ( )
361320 } else {
362321 input
363322 } ;
364323 let ParsedItem ( input, day) = one_or_two_digits ( input) . ok_or ( InvalidComponent ( "day" ) ) ?;
365324 let input = cfws ( input) . ok_or ( InvalidLiteral ) ?. into_inner ( ) ;
366- let ParsedItem ( input, month) = first_match (
367- [
368- ( b"Jan" . as_slice ( ) , Month :: January ) ,
369- ( b"Feb" . as_slice ( ) , Month :: February ) ,
370- ( b"Mar" . as_slice ( ) , Month :: March ) ,
371- ( b"Apr" . as_slice ( ) , Month :: April ) ,
372- ( b"May" . as_slice ( ) , Month :: May ) ,
373- ( b"Jun" . as_slice ( ) , Month :: June ) ,
374- ( b"Jul" . as_slice ( ) , Month :: July ) ,
375- ( b"Aug" . as_slice ( ) , Month :: August ) ,
376- ( b"Sep" . as_slice ( ) , Month :: September ) ,
377- ( b"Oct" . as_slice ( ) , Month :: October ) ,
378- ( b"Nov" . as_slice ( ) , Month :: November ) ,
379- ( b"Dec" . as_slice ( ) , Month :: December ) ,
380- ] ,
381- false ,
382- ) ( input)
325+ let ParsedItem ( input, month) = component:: parse_month (
326+ input,
327+ modifier:: Month {
328+ padding : modifier:: Padding :: None ,
329+ repr : modifier:: MonthRepr :: Short ,
330+ case_sensitive : false ,
331+ } ,
332+ )
383333 . ok_or ( InvalidComponent ( "month" ) ) ?;
384334 let input = cfws ( input) . ok_or ( InvalidLiteral ) ?. into_inner ( ) ;
385335 let ( input, year) = match ExactlyNDigits :: < 4 > :: parse ( input) {
@@ -421,34 +371,7 @@ impl sealed::Sealed for Rfc2822 {
421371 ( cfws ( input) . ok_or ( InvalidLiteral ) ?. into_inner ( ) , 0 )
422372 } ;
423373
424- #[ expect(
425- clippy:: unnecessary_lazy_evaluations,
426- reason = "rust-lang/rust-clippy#8522"
427- ) ]
428- let zone_literal = first_match (
429- [
430- ( b"UT" . as_slice ( ) , 0 ) ,
431- ( b"GMT" . as_slice ( ) , 0 ) ,
432- ( b"EST" . as_slice ( ) , -5 ) ,
433- ( b"EDT" . as_slice ( ) , -4 ) ,
434- ( b"CST" . as_slice ( ) , -6 ) ,
435- ( b"CDT" . as_slice ( ) , -5 ) ,
436- ( b"MST" . as_slice ( ) , -7 ) ,
437- ( b"MDT" . as_slice ( ) , -6 ) ,
438- ( b"PST" . as_slice ( ) , -8 ) ,
439- ( b"PDT" . as_slice ( ) , -7 ) ,
440- ] ,
441- false ,
442- ) ( input)
443- . or_else ( || match input {
444- [
445- b'a' ..=b'i' | b'k' ..=b'z' | b'A' ..=b'I' | b'K' ..=b'Z' ,
446- rest @ ..,
447- ] => Some ( ParsedItem ( rest, 0 ) ) ,
448- _ => None ,
449- } ) ;
450-
451- let ( input, offset_hour, offset_minute) = if let Some ( zone_literal) = zone_literal {
374+ let ( input, offset_hour, offset_minute) = if let Some ( zone_literal) = zone_literal ( input) {
452375 let ParsedItem ( input, offset_hour) = zone_literal;
453376 ( input, offset_hour, 0 )
454377 } else {
0 commit comments