@@ -127,89 +127,58 @@ impl<'a, I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>> DelayedFormat<I> {
127127 fn format_numeric ( & self , w : & mut impl Write , spec : & Numeric , pad : Pad ) -> fmt:: Result {
128128 use self :: Numeric :: * ;
129129
130- fn write_one ( w : & mut impl Write , v : u8 ) -> fmt:: Result {
131- w. write_char ( ( b'0' + v) as char )
132- }
133-
134- fn write_two ( w : & mut impl Write , v : u8 , pad : Pad ) -> fmt:: Result {
135- let ones = b'0' + v % 10 ;
136- match ( v / 10 , pad) {
137- ( 0 , Pad :: None ) => { }
138- ( 0 , Pad :: Space ) => w. write_char ( ' ' ) ?,
139- ( tens, _) => w. write_char ( ( b'0' + tens) as char ) ?,
130+ // unpack padding width if provided
131+ let ( spec, mut pad_width) = spec. unwrap_padding ( ) ;
132+
133+ let ( value, default_pad_width, is_year) = match ( spec, self . date , self . time ) {
134+ ( Year , Some ( d) , _) => ( d. year ( ) as i64 , 4 , true ) ,
135+ ( YearDiv100 , Some ( d) , _) => ( d. year ( ) . div_euclid ( 100 ) as i64 , 2 , false ) ,
136+ ( YearMod100 , Some ( d) , _) => ( d. year ( ) . rem_euclid ( 100 ) as i64 , 2 , false ) ,
137+ ( IsoYear , Some ( d) , _) => ( d. iso_week ( ) . year ( ) as i64 , 4 , true ) ,
138+ ( IsoYearDiv100 , Some ( d) , _) => ( d. iso_week ( ) . year ( ) . div_euclid ( 100 ) as i64 , 2 , false ) ,
139+ ( IsoYearMod100 , Some ( d) , _) => ( d. iso_week ( ) . year ( ) . rem_euclid ( 100 ) as i64 , 2 , false ) ,
140+ ( Quarter , Some ( d) , _) => ( d. quarter ( ) as i64 , 1 , false ) ,
141+ ( Month , Some ( d) , _) => ( d. month ( ) as i64 , 2 , false ) ,
142+ ( Day , Some ( d) , _) => ( d. day ( ) as i64 , 2 , false ) ,
143+ ( WeekFromSun , Some ( d) , _) => ( d. weeks_from ( Weekday :: Sun ) as i64 , 2 , false ) ,
144+ ( WeekFromMon , Some ( d) , _) => ( d. weeks_from ( Weekday :: Mon ) as i64 , 2 , false ) ,
145+ ( IsoWeek , Some ( d) , _) => ( d. iso_week ( ) . week ( ) as i64 , 2 , false ) ,
146+ ( NumDaysFromSun , Some ( d) , _) => ( d. weekday ( ) . num_days_from_sunday ( ) as i64 , 1 , false ) ,
147+ ( WeekdayFromMon , Some ( d) , _) => ( d. weekday ( ) . number_from_monday ( ) as i64 , 1 , false ) ,
148+ ( Ordinal , Some ( d) , _) => ( d. ordinal ( ) as i64 , 3 , false ) ,
149+ ( Hour , _, Some ( t) ) => ( t. hour ( ) as i64 , 2 , false ) ,
150+ ( Hour12 , _, Some ( t) ) => ( t. hour12 ( ) . 1 as i64 , 2 , false ) ,
151+ ( Minute , _, Some ( t) ) => ( t. minute ( ) as i64 , 2 , false ) ,
152+ ( Second , _, Some ( t) ) => {
153+ ( ( t. second ( ) + t. nanosecond ( ) / 1_000_000_000 ) as i64 , 2 , false )
140154 }
141- w. write_char ( ones as char )
142- }
143-
144- #[ inline]
145- fn write_year ( w : & mut impl Write , year : i32 , pad : Pad ) -> fmt:: Result {
146- if ( 1000 ..=9999 ) . contains ( & year) {
147- // fast path
148- write_hundreds ( w, ( year / 100 ) as u8 ) ?;
149- write_hundreds ( w, ( year % 100 ) as u8 )
150- } else {
151- write_n ( w, 4 , year as i64 , pad, !( 0 ..10_000 ) . contains ( & year) )
155+ ( Nanosecond , _, Some ( t) ) => ( ( t. nanosecond ( ) % 1_000_000_000 ) as i64 , 9 , false ) ,
156+ ( Timestamp , Some ( d) , Some ( t) ) => {
157+ let offset = self . off . as_ref ( ) . map ( |( _, o) | i64:: from ( o. local_minus_utc ( ) ) ) ;
158+ ( d. and_time ( t) . and_utc ( ) . timestamp ( ) - offset. unwrap_or ( 0 ) , 9 , false )
152159 }
153- }
160+ ( Internal ( _) , _, _) => return Ok ( ( ) ) , // for future expansion
161+ ( Padded { .. } , _, _) => return Err ( fmt:: Error ) , // should be unwrapped above
162+ _ => return Err ( fmt:: Error ) , // insufficient arguments for given format
163+ } ;
154164
155- fn write_n (
156- w : & mut impl Write ,
157- n : usize ,
158- v : i64 ,
159- pad : Pad ,
160- always_sign : bool ,
161- ) -> fmt:: Result {
162- if always_sign {
163- match pad {
164- Pad :: None => write ! ( w, "{:+}" , v) ,
165- Pad :: Zero => write ! ( w, "{:+01$}" , v, n + 1 ) ,
166- Pad :: Space => write ! ( w, "{:+1$}" , v, n + 1 ) ,
167- }
168- } else {
169- match pad {
170- Pad :: None => write ! ( w, "{}" , v) ,
171- Pad :: Zero => write ! ( w, "{:01$}" , v, n) ,
172- Pad :: Space => write ! ( w, "{:1$}" , v, n) ,
173- }
174- }
165+ if pad_width == 0 {
166+ pad_width = default_pad_width;
175167 }
176168
177- match ( spec, self . date , self . time ) {
178- ( Year , Some ( d) , _) => write_year ( w, d. year ( ) , pad) ,
179- ( YearDiv100 , Some ( d) , _) => write_two ( w, d. year ( ) . div_euclid ( 100 ) as u8 , pad) ,
180- ( YearMod100 , Some ( d) , _) => write_two ( w, d. year ( ) . rem_euclid ( 100 ) as u8 , pad) ,
181- ( IsoYear , Some ( d) , _) => write_year ( w, d. iso_week ( ) . year ( ) , pad) ,
182- ( IsoYearDiv100 , Some ( d) , _) => {
183- write_two ( w, d. iso_week ( ) . year ( ) . div_euclid ( 100 ) as u8 , pad)
184- }
185- ( IsoYearMod100 , Some ( d) , _) => {
186- write_two ( w, d. iso_week ( ) . year ( ) . rem_euclid ( 100 ) as u8 , pad)
187- }
188- ( Quarter , Some ( d) , _) => write_one ( w, d. quarter ( ) as u8 ) ,
189- ( Month , Some ( d) , _) => write_two ( w, d. month ( ) as u8 , pad) ,
190- ( Day , Some ( d) , _) => write_two ( w, d. day ( ) as u8 , pad) ,
191- ( WeekFromSun , Some ( d) , _) => write_two ( w, d. weeks_from ( Weekday :: Sun ) as u8 , pad) ,
192- ( WeekFromMon , Some ( d) , _) => write_two ( w, d. weeks_from ( Weekday :: Mon ) as u8 , pad) ,
193- ( IsoWeek , Some ( d) , _) => write_two ( w, d. iso_week ( ) . week ( ) as u8 , pad) ,
194- ( NumDaysFromSun , Some ( d) , _) => write_one ( w, d. weekday ( ) . num_days_from_sunday ( ) as u8 ) ,
195- ( WeekdayFromMon , Some ( d) , _) => write_one ( w, d. weekday ( ) . number_from_monday ( ) as u8 ) ,
196- ( Ordinal , Some ( d) , _) => write_n ( w, 3 , d. ordinal ( ) as i64 , pad, false ) ,
197- ( Hour , _, Some ( t) ) => write_two ( w, t. hour ( ) as u8 , pad) ,
198- ( Hour12 , _, Some ( t) ) => write_two ( w, t. hour12 ( ) . 1 as u8 , pad) ,
199- ( Minute , _, Some ( t) ) => write_two ( w, t. minute ( ) as u8 , pad) ,
200- ( Second , _, Some ( t) ) => {
201- write_two ( w, ( t. second ( ) + t. nanosecond ( ) / 1_000_000_000 ) as u8 , pad)
202- }
203- ( Nanosecond , _, Some ( t) ) => {
204- write_n ( w, 9 , ( t. nanosecond ( ) % 1_000_000_000 ) as i64 , pad, false )
169+ let always_sign = is_year && !( 0 ..10_000 ) . contains ( & value) ;
170+ if always_sign {
171+ match pad {
172+ Pad :: None => write ! ( w, "{:+}" , value) ,
173+ Pad :: Zero => write ! ( w, "{:+01$}" , value, pad_width + 1 ) ,
174+ Pad :: Space => write ! ( w, "{:+1$}" , value, pad_width + 1 ) ,
205175 }
206- ( Timestamp , Some ( d) , Some ( t) ) => {
207- let offset = self . off . as_ref ( ) . map ( |( _, o) | i64:: from ( o. local_minus_utc ( ) ) ) ;
208- let timestamp = d. and_time ( t) . and_utc ( ) . timestamp ( ) - offset. unwrap_or ( 0 ) ;
209- write_n ( w, 9 , timestamp, pad, false )
176+ } else {
177+ match pad {
178+ Pad :: None => write ! ( w, "{}" , value) ,
179+ Pad :: Zero => write ! ( w, "{:01$}" , value, pad_width) ,
180+ Pad :: Space => write ! ( w, "{:1$}" , value, pad_width) ,
210181 }
211- ( Internal ( _) , _, _) => Ok ( ( ) ) , // for future expansion
212- _ => Err ( fmt:: Error ) , // insufficient arguments for given format
213182 }
214183 }
215184
0 commit comments