1mod component_provider;
4pub(crate) mod formattable;
5mod iso8601;
6mod metadata;
7
8use core::mem::MaybeUninit;
9use core::num::NonZero;
10use std::io;
11
12use deranged::{Option_ri32, Option_ru8, ri8, ri16, ri32, ru8, ru16, ru32};
13use num_conv::prelude::*;
14
15use self::component_provider::ComponentProvider;
16pub use self::formattable::Formattable;
17use crate::format_description::{Period, modifier};
18use crate::internal_macros::try_likely_ok;
19use crate::time::{Hours, Minutes, Nanoseconds, Seconds};
20use crate::utc_offset::{Hours as OffsetHours, Minutes as OffsetMinutes, Seconds as OffsetSeconds};
21use crate::{Month, Weekday, error, num_fmt};
22
23type Day = ru8<1, 31>;
24type OptionDay = Option_ru8<1, 31>;
25type Ordinal = ru16<1, 366>;
26type IsoWeekNumber = ru8<1, 53>;
27type OptionIsoWeekNumber = Option_ru8<1, 53>;
28type MondayBasedWeek = ru8<0, 53>;
29type SundayBasedWeek = ru8<0, 53>;
30type Year = ri32<-999_999, 999_999>;
31type StandardYear = ri16<-9_999, 9_999>;
32type OptionYear = Option_ri32<-999_999, 999_999>;
33type ExtendedCentury = ri16<-9_999, 9_999>;
34type StandardCentury = ri8<-99, 99>;
35type LastTwo = ru8<0, 99>;
36
37const MONTH_NAMES: [&str; 12] = [
38 "January",
39 "February",
40 "March",
41 "April",
42 "May",
43 "June",
44 "July",
45 "August",
46 "September",
47 "October",
48 "November",
49 "December",
50];
51
52const WEEKDAY_NAMES: [&str; 7] = [
53 "Monday",
54 "Tuesday",
55 "Wednesday",
56 "Thursday",
57 "Friday",
58 "Saturday",
59 "Sunday",
60];
61
62#[inline]
67fn f64_10_pow_x(x: NonZero<u8>) -> f64 {
68 match x.get() {
69 1 => 10.,
70 2 => 100.,
71 3 => 1_000.,
72 4 => 10_000.,
73 5 => 100_000.,
74 6 => 1_000_000.,
75 7 => 10_000_000.,
76 8 => 100_000_000.,
77 9 => 1_000_000_000.,
78 x => 10_f64.powi(x.cast_signed().widen()),
79 }
80}
81
82#[derive(Debug)]
84pub(crate) struct Output<W>
85where
86 W: ?Sized,
87{
88 pub(crate) bytes_written: usize,
90 pub(crate) output: W,
92}
93
94impl<W> Output<W>
95where
96 W: io::Write + ?Sized,
97{
98 #[inline]
100 pub(crate) fn write(&mut self, s: &str) -> io::Result<()> {
101 try_likely_ok!(self.output.write_all(s.as_bytes()));
102 self.bytes_written += s.len();
103 Ok(())
104 }
105
106 #[inline]
108 pub(crate) fn write_bytes(&mut self, bytes: &[u8]) -> io::Result<()> {
109 try_likely_ok!(self.output.write_all(bytes));
110 self.bytes_written += bytes.len();
111 Ok(())
112 }
113
114 #[inline]
116 pub(crate) fn write_many<const N: usize>(&mut self, arr: [&str; N]) -> io::Result<()> {
117 for s in arr {
118 try_likely_ok!(self.write(s));
119 }
120 Ok(())
121 }
122
123 pub(crate) fn write_if(&mut self, pred: bool, s: &str) -> io::Result<()> {
125 if pred { self.write(s) } else { Ok(()) }
126 }
127
128 #[inline]
130 pub(crate) fn write_if_else(
131 &mut self,
132 pred: bool,
133 true_str: &str,
134 false_str: &str,
135 ) -> io::Result<()> {
136 self.write(if pred { true_str } else { false_str })
137 }
138
139 #[inline]
144 fn format_int_padded(&mut self, value: u64, width: u8) -> io::Result<()> {
145 let s = num_fmt::u64_pad_none(value);
146 let digit_count = s.len() as u8;
147 for _ in digit_count..width {
148 try_likely_ok!(self.write("0"));
149 }
150 try_likely_ok!(self.write(&s));
151 Ok(())
152 }
153
154 #[inline]
159 pub(crate) fn format_float(
160 &mut self,
161 mut value: f64,
162 digits_before_decimal: u8,
163 digits_after_decimal: Option<NonZero<u8>>,
164 ) -> io::Result<()> {
165 match digits_after_decimal {
166 Some(digits_after_decimal) => {
167 if digits_after_decimal.get() < 9 {
181 let trunc_num = f64_10_pow_x(digits_after_decimal);
182 value = f64::trunc(value * trunc_num) / trunc_num;
183
184 let int_part = value.trunc() as u64;
185 let frac_part =
186 f64::round(value.fract() * f64_10_pow_x(digits_after_decimal)) as u64;
187
188 try_likely_ok!(self.format_int_padded(int_part, digits_before_decimal.widen()));
189 try_likely_ok!(self.write("."));
190 try_likely_ok!(
191 self.format_int_padded(frac_part, digits_after_decimal.get().widen())
192 );
193 } else {
194 let digits_after = digits_after_decimal.get().widen::<usize>();
198 let width = digits_before_decimal.widen::<usize>() + 1 + digits_after;
199 try_likely_ok!(write!(self.output, "{value:0>width$.digits_after$}"));
200 self.bytes_written += width;
201 }
202 Ok(())
203 }
204 None => self.format_int_padded(value.trunc() as u64, digits_before_decimal),
205 }
206 }
207
208 #[inline]
210 pub(crate) fn format_single_digit(&mut self, value: ru8<0, 9>) -> io::Result<()> {
211 self.write(num_fmt::single_digit(value))
212 }
213
214 #[inline]
216 pub(crate) fn format_two_digits(
217 &mut self,
218 value: ru8<0, 99>,
219 padding: modifier::Padding,
220 ) -> io::Result<()> {
221 let s = match padding {
222 modifier::Padding::Space => num_fmt::two_digits_space_padded(value),
223 modifier::Padding::Zero => num_fmt::two_digits_zero_padded(value),
224 modifier::Padding::None => num_fmt::one_to_two_digits_no_padding(value),
225 };
226 self.write(s)
227 }
228
229 #[inline]
231 pub(crate) fn format_three_digits(
232 &mut self,
233 value: ru16<0, 999>,
234 padding: modifier::Padding,
235 ) -> io::Result<()> {
236 let [first, second_and_third] = match padding {
237 modifier::Padding::Space => num_fmt::three_digits_space_padded(value),
238 modifier::Padding::Zero => num_fmt::three_digits_zero_padded(value),
239 modifier::Padding::None => num_fmt::one_to_three_digits_no_padding(value),
240 };
241 self.write_many([first, second_and_third])
242 }
243
244 #[inline]
246 pub(crate) fn format_four_digits(
247 &mut self,
248 value: ru16<0, 9_999>,
249 padding: modifier::Padding,
250 ) -> io::Result<()> {
251 let [first_and_second, third_and_fourth] = match padding {
252 modifier::Padding::Space => num_fmt::four_digits_space_padded(value),
253 modifier::Padding::Zero => num_fmt::four_digits_zero_padded(value),
254 modifier::Padding::None => num_fmt::one_to_four_digits_no_padding(value),
255 };
256 self.write_many([first_and_second, third_and_fourth])
257 }
258
259 #[inline]
261 pub(crate) fn format_four_digits_pad_zero(&mut self, value: ru16<0, 9_999>) -> io::Result<()> {
262 self.write_many(num_fmt::four_digits_zero_padded(value))
263 }
264
265 #[inline]
267 pub(crate) fn format_five_digits_pad_zero(&mut self, value: ru32<0, 99_999>) -> io::Result<()> {
268 self.write_many(num_fmt::five_digits_zero_padded(value))
269 }
270
271 #[inline]
273 pub(crate) fn format_six_digits_pad_zero(&mut self, value: ru32<0, 999_999>) -> io::Result<()> {
274 self.write_many(num_fmt::six_digits_zero_padded(value))
275 }
276
277 #[inline]
281 pub(crate) fn format_u64_pad_none(&mut self, value: u64) -> io::Result<()> {
282 self.write(&num_fmt::u64_pad_none(value))
283 }
284
285 #[inline]
289 pub(crate) fn format_u128_pad_none(&mut self, value: u128) -> io::Result<()> {
290 self.write(&num_fmt::u128_pad_none(value))
291 }
292
293 #[inline]
295 fn fmt_day(
296 &mut self,
297 day: Day,
298 modifier::Day { padding }: modifier::Day,
299 ) -> Result<(), io::Error> {
300 self.format_two_digits(day.expand(), padding)
301 }
302
303 #[inline]
305 fn fmt_month_short(
306 &mut self,
307 month: Month,
308 modifier::MonthShort {
309 case_sensitive: _, }: modifier::MonthShort,
311 ) -> io::Result<()> {
312 self.write(unsafe { MONTH_NAMES[u8::from(month).widen::<usize>() - 1].get_unchecked(..3) })
314 }
315
316 #[inline]
318 fn fmt_month_long(
319 &mut self,
320 month: Month,
321 modifier::MonthLong {
322 case_sensitive: _, }: modifier::MonthLong,
324 ) -> io::Result<()> {
325 self.write(MONTH_NAMES[u8::from(month).widen::<usize>() - 1])
326 }
327
328 #[inline]
330 fn fmt_month_numerical(
331 &mut self,
332 month: Month,
333 modifier::MonthNumerical { padding }: modifier::MonthNumerical,
334 ) -> io::Result<()> {
335 self.format_two_digits(unsafe { ru8::new_unchecked(u8::from(month)) }, padding)
337 }
338
339 #[inline]
341 fn fmt_ordinal(
342 &mut self,
343 ordinal: Ordinal,
344 modifier::Ordinal { padding }: modifier::Ordinal,
345 ) -> Result<(), io::Error> {
346 self.format_three_digits(ordinal.expand(), padding)
347 }
348
349 #[inline]
351 fn fmt_weekday_short(
352 &mut self,
353 weekday: Weekday,
354 modifier::WeekdayShort {
355 case_sensitive: _, }: modifier::WeekdayShort,
357 ) -> io::Result<()> {
358 self.write(unsafe {
360 WEEKDAY_NAMES[weekday.number_days_from_monday().widen::<usize>()].get_unchecked(..3)
361 })
362 }
363
364 #[inline]
366 fn fmt_weekday_long(
367 &mut self,
368 weekday: Weekday,
369 modifier::WeekdayLong {
370 case_sensitive: _, }: modifier::WeekdayLong,
372 ) -> io::Result<()> {
373 self.write(WEEKDAY_NAMES[weekday.number_days_from_monday().widen::<usize>()])
374 }
375
376 #[inline]
379 fn fmt_weekday_sunday(
380 &mut self,
381 weekday: Weekday,
382 modifier::WeekdaySunday { one_indexed }: modifier::WeekdaySunday,
383 ) -> io::Result<()> {
384 self.format_single_digit(unsafe {
386 ru8::new_unchecked(weekday.number_days_from_sunday() + u8::from(one_indexed))
387 })
388 }
389
390 #[inline]
393 fn fmt_weekday_monday(
394 &mut self,
395 weekday: Weekday,
396 modifier::WeekdayMonday { one_indexed }: modifier::WeekdayMonday,
397 ) -> io::Result<()> {
398 self.format_single_digit(unsafe {
400 ru8::new_unchecked(weekday.number_days_from_monday() + u8::from(one_indexed))
401 })
402 }
403
404 #[inline]
405 fn fmt_week_number_iso(
406 &mut self,
407 week_number: IsoWeekNumber,
408 modifier::WeekNumberIso { padding }: modifier::WeekNumberIso,
409 ) -> io::Result<()> {
410 self.format_two_digits(week_number.expand(), padding)
411 }
412
413 #[inline]
414 fn fmt_week_number_sunday(
415 &mut self,
416 week_number: SundayBasedWeek,
417 modifier::WeekNumberSunday { padding }: modifier::WeekNumberSunday,
418 ) -> io::Result<()> {
419 self.format_two_digits(week_number.expand(), padding)
420 }
421
422 #[inline]
423 fn fmt_week_number_monday(
424 &mut self,
425 week_number: MondayBasedWeek,
426 modifier::WeekNumberMonday { padding }: modifier::WeekNumberMonday,
427 ) -> io::Result<()> {
428 self.format_two_digits(week_number.expand(), padding)
429 }
430
431 #[inline]
432 fn fmt_calendar_year_full_extended_range(
433 &mut self,
434 full_year: Year,
435 modifier::CalendarYearFullExtendedRange {
436 padding,
437 sign_is_mandatory,
438 }: modifier::CalendarYearFullExtendedRange,
439 ) -> io::Result<()> {
440 try_likely_ok!(self.fmt_sign(
441 full_year.is_negative(),
442 sign_is_mandatory || full_year.get() >= 10_000
443 ));
444 let value: ru32<0, 999_999> =
447 unsafe { full_year.abs().narrow_unchecked::<0, 999_999>().into() };
448
449 if let Some(value) = value.narrow::<0, 9_999>() {
450 try_likely_ok!(self.format_four_digits(value.into(), padding))
451 } else if let Some(value) = value.narrow::<0, 99_999>() {
452 try_likely_ok!(self.format_five_digits_pad_zero(value))
453 } else {
454 try_likely_ok!(self.format_six_digits_pad_zero(value))
455 };
456 Ok(())
457 }
458
459 #[inline]
460 fn fmt_calendar_year_full_standard_range(
461 &mut self,
462 full_year: StandardYear,
463 modifier::CalendarYearFullStandardRange {
464 padding,
465 sign_is_mandatory,
466 }: modifier::CalendarYearFullStandardRange,
467 ) -> io::Result<()> {
468 try_likely_ok!(self.fmt_sign(full_year.is_negative(), sign_is_mandatory));
469 try_likely_ok!(self.format_four_digits(
470 unsafe { full_year.abs().narrow_unchecked::<0, 9_999>().into() },
472 padding
473 ));
474 Ok(())
475 }
476
477 #[inline]
478 fn fmt_iso_year_full_extended_range(
479 &mut self,
480 full_year: Year,
481 modifier::IsoYearFullExtendedRange {
482 padding,
483 sign_is_mandatory,
484 }: modifier::IsoYearFullExtendedRange,
485 ) -> io::Result<()> {
486 try_likely_ok!(self.fmt_sign(
487 full_year.is_negative(),
488 sign_is_mandatory || full_year.get() >= 10_000
489 ));
490 let value: ru32<0, 999_999> =
492 unsafe { full_year.abs().narrow_unchecked::<0, 999_999>().into() };
493
494 if let Some(value) = value.narrow::<0, 9_999>() {
495 try_likely_ok!(self.format_four_digits(value.into(), padding))
496 } else if let Some(value) = value.narrow::<0, 99_999>() {
497 try_likely_ok!(self.format_five_digits_pad_zero(value))
498 } else {
499 try_likely_ok!(self.format_six_digits_pad_zero(value))
500 };
501 Ok(())
502 }
503
504 #[inline]
505 fn fmt_iso_year_full_standard_range(
506 &mut self,
507 year: StandardYear,
508 modifier::IsoYearFullStandardRange {
509 padding,
510 sign_is_mandatory,
511 }: modifier::IsoYearFullStandardRange,
512 ) -> io::Result<()> {
513 try_likely_ok!(self.fmt_sign(year.is_negative(), sign_is_mandatory));
514 try_likely_ok!(self.format_four_digits(
515 unsafe { year.abs().narrow_unchecked::<0, 9_999>().into() },
517 padding
518 ));
519 Ok(())
520 }
521
522 #[inline]
523 fn fmt_calendar_year_century_extended_range(
524 &mut self,
525 century: ExtendedCentury,
526 is_negative: bool,
527 modifier::CalendarYearCenturyExtendedRange {
528 padding,
529 sign_is_mandatory,
530 }: modifier::CalendarYearCenturyExtendedRange,
531 ) -> io::Result<()> {
532 try_likely_ok!(self.fmt_sign(is_negative, sign_is_mandatory || century.get() >= 100));
533 let century: ru16<0, 9_999> =
535 unsafe { century.abs().narrow_unchecked::<0, 9_999>().into() };
536
537 if let Some(century) = century.narrow::<0, 99>() {
538 try_likely_ok!(self.format_two_digits(century.into(), padding))
539 } else if let Some(century) = century.narrow::<0, 999>() {
540 try_likely_ok!(self.format_three_digits(century, padding))
541 } else {
542 try_likely_ok!(self.format_four_digits(century, padding))
543 };
544 Ok(())
545 }
546
547 #[inline]
548 fn fmt_calendar_year_century_standard_range(
549 &mut self,
550 century: StandardCentury,
551 is_negative: bool,
552 modifier::CalendarYearCenturyStandardRange {
553 padding,
554 sign_is_mandatory,
555 }: modifier::CalendarYearCenturyStandardRange,
556 ) -> io::Result<()> {
557 try_likely_ok!(self.fmt_sign(is_negative, sign_is_mandatory));
558 let century = unsafe { century.abs().narrow_unchecked::<0, 99>() };
560 try_likely_ok!(self.format_two_digits(century.into(), padding));
561 Ok(())
562 }
563
564 #[inline]
565 fn fmt_iso_year_century_extended_range(
566 &mut self,
567 century: ExtendedCentury,
568 is_negative: bool,
569 modifier::IsoYearCenturyExtendedRange {
570 padding,
571 sign_is_mandatory,
572 }: modifier::IsoYearCenturyExtendedRange,
573 ) -> io::Result<()> {
574 try_likely_ok!(self.fmt_sign(is_negative, sign_is_mandatory || century.get() >= 100));
575 let century: ru16<0, 9_999> =
578 unsafe { century.abs().narrow_unchecked::<0, 9_999>().into() };
579
580 if let Some(century) = century.narrow::<0, 99>() {
581 try_likely_ok!(self.format_two_digits(century.into(), padding))
582 } else if let Some(century) = century.narrow::<0, 999>() {
583 try_likely_ok!(self.format_three_digits(century, padding))
584 } else {
585 try_likely_ok!(self.format_four_digits(century, padding))
586 };
587 Ok(())
588 }
589
590 #[inline]
591 fn fmt_iso_year_century_standard_range(
592 &mut self,
593 century: StandardCentury,
594 is_negative: bool,
595 modifier::IsoYearCenturyStandardRange {
596 padding,
597 sign_is_mandatory,
598 }: modifier::IsoYearCenturyStandardRange,
599 ) -> io::Result<()> {
600 try_likely_ok!(self.fmt_sign(is_negative, sign_is_mandatory));
601 let century = unsafe { century.abs().narrow_unchecked::<0, 99>() };
603 try_likely_ok!(self.format_two_digits(century.into(), padding));
604 Ok(())
605 }
606
607 #[inline]
608 fn fmt_calendar_year_last_two(
609 &mut self,
610 last_two: LastTwo,
611 modifier::CalendarYearLastTwo { padding }: modifier::CalendarYearLastTwo,
612 ) -> io::Result<()> {
613 self.format_two_digits(last_two, padding)
614 }
615
616 #[inline]
617 fn fmt_iso_year_last_two(
618 &mut self,
619 last_two: LastTwo,
620 modifier::IsoYearLastTwo { padding }: modifier::IsoYearLastTwo,
621 ) -> io::Result<()> {
622 self.format_two_digits(last_two, padding)
623 }
624
625 #[inline]
627 fn fmt_hour_12(
628 &mut self,
629 hour: Hours,
630 modifier::Hour12 { padding }: modifier::Hour12,
631 ) -> io::Result<()> {
632 self.format_two_digits(
634 unsafe { ru8::new_unchecked((hour.get() + 11) % 12 + 1) },
635 padding,
636 )
637 }
638
639 #[inline]
641 fn fmt_hour_24(
642 &mut self,
643 hour: Hours,
644 modifier::Hour24 { padding }: modifier::Hour24,
645 ) -> io::Result<()> {
646 self.format_two_digits(hour.expand(), padding)
647 }
648
649 #[inline]
651 fn fmt_minute(
652 &mut self,
653 minute: Minutes,
654 modifier::Minute { padding }: modifier::Minute,
655 ) -> Result<(), io::Error> {
656 self.format_two_digits(minute.expand(), padding)
657 }
658
659 #[inline]
661 fn fmt_period(
662 &mut self,
663 period: Period,
664 modifier::Period {
665 is_uppercase,
666 case_sensitive: _, }: modifier::Period,
668 ) -> Result<(), io::Error> {
669 self.write(match (period, is_uppercase) {
670 (Period::Am, false) => "am",
671 (Period::Am, true) => "AM",
672 (Period::Pm, false) => "pm",
673 (Period::Pm, true) => "PM",
674 })
675 }
676
677 #[inline]
679 fn fmt_second(
680 &mut self,
681 second: Seconds,
682 modifier::Second { padding }: modifier::Second,
683 ) -> Result<(), io::Error> {
684 self.format_two_digits(second.expand(), padding)
685 }
686
687 #[inline]
689 fn fmt_subsecond(
690 &mut self,
691 nanos: Nanoseconds,
692 modifier::Subsecond { digits }: modifier::Subsecond,
693 ) -> Result<(), io::Error> {
694 use modifier::SubsecondDigits::*;
695
696 #[repr(C, align(8))]
697 #[derive(Clone, Copy)]
698 struct Digits {
699 _padding: MaybeUninit<[u8; 7]>,
700 digit_1: u8,
701 digits_2_thru_9: [u8; 8],
702 }
703
704 let [
705 digit_1,
706 digits_2_and_3,
707 digits_4_and_5,
708 digits_6_and_7,
709 digits_8_and_9,
710 ] = num_fmt::subsecond_from_nanos(nanos);
711
712 let buf = Digits {
716 _padding: MaybeUninit::uninit(),
717 digit_1: digit_1.as_bytes()[0],
718 digits_2_thru_9: [
719 digits_2_and_3.as_bytes()[0],
720 digits_2_and_3.as_bytes()[1],
721 digits_4_and_5.as_bytes()[0],
722 digits_4_and_5.as_bytes()[1],
723 digits_6_and_7.as_bytes()[0],
724 digits_6_and_7.as_bytes()[1],
725 digits_8_and_9.as_bytes()[0],
726 digits_8_and_9.as_bytes()[1],
727 ],
728 };
729
730 let len = match digits {
731 One => 1,
732 Two => 2,
733 Three => 3,
734 Four => 4,
735 Five => 5,
736 Six => 6,
737 Seven => 7,
738 Eight => 8,
739 Nine => 9,
740 OneOrMore => {
741 let bitmask =
746 u64::from_le_bytes(buf.digits_2_thru_9) ^ u64::from_le_bytes([b'0'; 8]);
747 let digits_to_truncate = bitmask.leading_zeros() / 8;
748 9 - digits_to_truncate as usize
749 }
750 };
751
752 let s = unsafe {
756 num_fmt::StackStr::new(
757 *(&raw const buf)
758 .byte_add(core::mem::offset_of!(Digits, digit_1))
759 .cast::<[MaybeUninit<u8>; 9]>(),
760 len,
761 )
762 };
763 self.write(&s)
764 }
765
766 #[inline]
767 fn fmt_sign(&mut self, is_negative: bool, sign_is_mandatory: bool) -> io::Result<()> {
768 if is_negative {
769 self.write("-")
770 } else if sign_is_mandatory {
771 self.write("+")
772 } else {
773 Ok(())
774 }
775 }
776
777 #[inline]
779 fn fmt_offset_hour(
780 &mut self,
781 is_negative: bool,
782 hour: OffsetHours,
783 modifier::OffsetHour {
784 padding,
785 sign_is_mandatory,
786 }: modifier::OffsetHour,
787 ) -> Result<(), io::Error> {
788 try_likely_ok!(self.fmt_sign(is_negative, sign_is_mandatory));
789 try_likely_ok!(self.format_two_digits(
790 unsafe { ru8::new_unchecked(hour.get().unsigned_abs()) },
792 padding,
793 ));
794 Ok(())
795 }
796
797 #[inline]
799 fn fmt_offset_minute(
800 &mut self,
801 offset_minute: OffsetMinutes,
802 modifier::OffsetMinute { padding }: modifier::OffsetMinute,
803 ) -> Result<(), io::Error> {
804 self.format_two_digits(
805 unsafe { ru8::new_unchecked(offset_minute.get().unsigned_abs()) },
808 padding,
809 )
810 }
811
812 #[inline]
814 fn fmt_offset_second(
815 &mut self,
816 offset_second: OffsetSeconds,
817 modifier::OffsetSecond { padding }: modifier::OffsetSecond,
818 ) -> Result<(), io::Error> {
819 self.format_two_digits(
820 unsafe { ru8::new_unchecked(offset_second.get().unsigned_abs()) },
823 padding,
824 )
825 }
826
827 #[inline]
829 fn fmt_unix_timestamp_second(
830 &mut self,
831 timestamp: i64,
832 modifier::UnixTimestampSecond { sign_is_mandatory }: modifier::UnixTimestampSecond,
833 ) -> Result<(), io::Error> {
834 try_likely_ok!(self.fmt_sign(timestamp < 0, sign_is_mandatory));
835 try_likely_ok!(self.format_u64_pad_none(timestamp.unsigned_abs()));
836 Ok(())
837 }
838
839 #[inline]
841 fn fmt_unix_timestamp_millisecond(
842 &mut self,
843 timestamp_millis: i64,
844 modifier::UnixTimestampMillisecond { sign_is_mandatory }:
845 modifier::UnixTimestampMillisecond,
846 ) -> Result<(), io::Error> {
847 try_likely_ok!(self.fmt_sign(timestamp_millis < 0, sign_is_mandatory));
848 try_likely_ok!(self.format_u64_pad_none(timestamp_millis.unsigned_abs()));
849 Ok(())
850 }
851
852 #[inline]
854 fn fmt_unix_timestamp_microsecond(
855 &mut self,
856 timestamp_micros: i128,
857 modifier::UnixTimestampMicrosecond { sign_is_mandatory }:
858 modifier::UnixTimestampMicrosecond,
859 ) -> Result<(), io::Error> {
860 try_likely_ok!(self.fmt_sign(timestamp_micros < 0, sign_is_mandatory));
861 try_likely_ok!(self.format_u128_pad_none(timestamp_micros.unsigned_abs()));
862 Ok(())
863 }
864
865 #[inline]
867 fn fmt_unix_timestamp_nanosecond(
868 &mut self,
869 timestamp_nanos: i128,
870 modifier::UnixTimestampNanosecond { sign_is_mandatory }: modifier::UnixTimestampNanosecond,
871 ) -> Result<(), io::Error> {
872 try_likely_ok!(self.fmt_sign(timestamp_nanos < 0, sign_is_mandatory));
873 try_likely_ok!(self.format_u128_pad_none(timestamp_nanos.unsigned_abs()));
874 Ok(())
875 }
876}