1use std::fmt::Write as _;
2
3use super::{
4 Encode, EncodeFast, FORMAT_ALIGN_NONE, FORMAT_ALIGN_RIGHT, FORMAT_PRECISION_NONE,
5 format::{
6 VecWriter, append_binary_u64_padded_const, append_const_float_body,
7 append_display_with_spec, append_float_with_spec, append_i32_decimal_with_spec,
8 append_i64_decimal_with_spec, append_integer_with_spec_cast,
9 append_lower_hex_u64_padded_const, append_octal_u64_padded_const, append_padded_const,
10 append_ryu_float, append_u32_decimal_with_spec, append_u64_decimal_with_spec,
11 append_upper_hex_u64_padded_const,
12 },
13 traits::{
14 EncodeBinary, EncodeConstBinaryFormat, EncodeConstDefaultFormat, EncodeConstFloatFormat,
15 EncodeConstLowerHexFormat, EncodeConstOctalFormat, EncodeConstUpperHexFormat,
16 EncodeLowerHex, EncodeOctal, EncodeUpperHex,
17 },
18};
19use crate::number_format;
20
21macro_rules! impl_integer_encode {
24 ($type:ty, $append_function:path, $cast:expr, $append_decimal:expr) => {
25 impl Encode for $type {
26 const ENCODED_SIZE_HINT: usize = std::mem::size_of::<$type>();
27
28 #[inline(always)]
29 fn encoded_size(&self) -> usize {
30 std::mem::size_of::<$type>()
31 }
32
33 #[inline(always)]
34 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
35 unsafe {
36 buffer.add(*offset).cast::<$type>().write_unaligned(*self);
37 }
38 *offset += std::mem::size_of::<$type>();
39 }
40
41 #[inline(always)]
42 unsafe fn encode_at_offset(&self, buffer: *mut u8, offset: usize) {
43 unsafe {
44 buffer.add(offset).cast::<$type>().write_unaligned(*self);
45 }
46 }
47
48 #[inline]
49 unsafe fn decode_and_format(
50 buffer: *const u8,
51 offset: &mut usize,
52 output: &mut Vec<u8>,
53 format_spec: &str,
54 ) {
55 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
56 *offset += std::mem::size_of::<$type>();
57 if format_spec.is_empty() {
58 $append_function(output, value);
59 } else {
60 append_integer_with_spec_cast(
61 output,
62 value,
63 ($cast)(value),
64 format_spec,
65 |output, spec| ($append_decimal)(output, value, spec),
66 );
67 }
68 }
69
70 #[inline]
71 unsafe fn decode_and_format_at_offset(
72 buffer: *const u8,
73 offset: usize,
74 output: &mut Vec<u8>,
75 format_spec: &str,
76 ) {
77 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
78 if format_spec.is_empty() {
79 $append_function(output, value);
80 } else {
81 append_integer_with_spec_cast(
82 output,
83 value,
84 ($cast)(value),
85 format_spec,
86 |output, spec| ($append_decimal)(output, value, spec),
87 );
88 }
89 }
90 }
91
92 unsafe impl EncodeFast for $type {
93 #[inline(always)]
94 unsafe fn decode_and_append_fast_at_offset(
95 buffer: *const u8,
96 offset: usize,
97 output: &mut Vec<u8>,
98 ) {
99 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
100 $append_function(output, value);
101 }
102 }
103 };
104}
105
106impl_integer_encode!(
108 i32,
109 number_format::append_i32,
110 |value: i32| (value as u32) as u64,
111 append_i32_decimal_with_spec
112);
113impl_integer_encode!(
114 u32,
115 number_format::append_u32,
116 |value: u32| value as u64,
117 append_u32_decimal_with_spec
118);
119impl_integer_encode!(
120 i64,
121 number_format::append_i64,
122 |value: i64| value as u64,
123 append_i64_decimal_with_spec
124);
125impl_integer_encode!(
126 u64,
127 number_format::append_u64,
128 |value: u64| value,
129 append_u64_decimal_with_spec
130);
131impl_integer_encode!(
132 usize,
133 number_format::append_u64_from_usize,
134 |value: usize| value as u64,
135 |output, value, spec| append_u64_decimal_with_spec(output, value as u64, spec)
136);
137impl_integer_encode!(
138 isize,
139 number_format::append_i64_from_isize,
140 |value: isize| { (value as usize) as u64 },
141 |output, value, spec| append_i64_decimal_with_spec(output, value as i64, spec)
142);
143macro_rules! impl_unsigned_integer_format_traits {
144 ($type:ty, $read:expr) => {
145 impl EncodeLowerHex for $type {
146 #[inline]
147 unsafe fn decode_append_lower_hex<const ALTERNATE: bool>(
148 buffer: *const u8,
149 offset: &mut usize,
150 output: &mut Vec<u8>,
151 ) {
152 let value = ($read)(buffer, offset);
153 append_lower_hex_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
154 output,
155 value as u64,
156 );
157 }
158
159 #[inline]
160 unsafe fn decode_append_lower_hex_at_offset<const ALTERNATE: bool>(
161 buffer: *const u8,
162 offset: usize,
163 output: &mut Vec<u8>,
164 ) {
165 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
166 append_lower_hex_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
167 output,
168 value as u64,
169 );
170 }
171 }
172
173 impl EncodeUpperHex for $type {
174 #[inline]
175 unsafe fn decode_append_upper_hex<const ALTERNATE: bool>(
176 buffer: *const u8,
177 offset: &mut usize,
178 output: &mut Vec<u8>,
179 ) {
180 let value = ($read)(buffer, offset);
181 append_upper_hex_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
182 output,
183 value as u64,
184 );
185 }
186
187 #[inline]
188 unsafe fn decode_append_upper_hex_at_offset<const ALTERNATE: bool>(
189 buffer: *const u8,
190 offset: usize,
191 output: &mut Vec<u8>,
192 ) {
193 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
194 append_upper_hex_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
195 output,
196 value as u64,
197 );
198 }
199 }
200
201 impl EncodeBinary for $type {
202 #[inline]
203 unsafe fn decode_append_binary<const ALTERNATE: bool>(
204 buffer: *const u8,
205 offset: &mut usize,
206 output: &mut Vec<u8>,
207 ) {
208 let value = ($read)(buffer, offset);
209 append_binary_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
210 output,
211 value as u64,
212 );
213 }
214
215 #[inline]
216 unsafe fn decode_append_binary_at_offset<const ALTERNATE: bool>(
217 buffer: *const u8,
218 offset: usize,
219 output: &mut Vec<u8>,
220 ) {
221 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
222 append_binary_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
223 output,
224 value as u64,
225 );
226 }
227 }
228
229 impl EncodeOctal for $type {
230 #[inline]
231 unsafe fn decode_append_octal<const ALTERNATE: bool>(
232 buffer: *const u8,
233 offset: &mut usize,
234 output: &mut Vec<u8>,
235 ) {
236 let value = ($read)(buffer, offset);
237 append_octal_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
238 output,
239 value as u64,
240 );
241 }
242
243 #[inline]
244 unsafe fn decode_append_octal_at_offset<const ALTERNATE: bool>(
245 buffer: *const u8,
246 offset: usize,
247 output: &mut Vec<u8>,
248 ) {
249 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
250 append_octal_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
251 output,
252 value as u64,
253 );
254 }
255 }
256 };
257}
258
259macro_rules! impl_signed_integer_format_traits {
260 ($type:ty, $read:expr, $cast:expr) => {
261 impl EncodeLowerHex for $type {
262 #[inline]
263 unsafe fn decode_append_lower_hex<const ALTERNATE: bool>(
264 buffer: *const u8,
265 offset: &mut usize,
266 output: &mut Vec<u8>,
267 ) {
268 let value = ($read)(buffer, offset);
269 append_lower_hex_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
270 output,
271 ($cast)(value),
272 );
273 }
274
275 #[inline]
276 unsafe fn decode_append_lower_hex_at_offset<const ALTERNATE: bool>(
277 buffer: *const u8,
278 offset: usize,
279 output: &mut Vec<u8>,
280 ) {
281 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
282 append_lower_hex_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
283 output,
284 ($cast)(value),
285 );
286 }
287 }
288
289 impl EncodeUpperHex for $type {
290 #[inline]
291 unsafe fn decode_append_upper_hex<const ALTERNATE: bool>(
292 buffer: *const u8,
293 offset: &mut usize,
294 output: &mut Vec<u8>,
295 ) {
296 let value = ($read)(buffer, offset);
297 append_upper_hex_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
298 output,
299 ($cast)(value),
300 );
301 }
302
303 #[inline]
304 unsafe fn decode_append_upper_hex_at_offset<const ALTERNATE: bool>(
305 buffer: *const u8,
306 offset: usize,
307 output: &mut Vec<u8>,
308 ) {
309 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
310 append_upper_hex_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
311 output,
312 ($cast)(value),
313 );
314 }
315 }
316
317 impl EncodeBinary for $type {
318 #[inline]
319 unsafe fn decode_append_binary<const ALTERNATE: bool>(
320 buffer: *const u8,
321 offset: &mut usize,
322 output: &mut Vec<u8>,
323 ) {
324 let value = ($read)(buffer, offset);
325 append_binary_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
326 output,
327 ($cast)(value),
328 );
329 }
330
331 #[inline]
332 unsafe fn decode_append_binary_at_offset<const ALTERNATE: bool>(
333 buffer: *const u8,
334 offset: usize,
335 output: &mut Vec<u8>,
336 ) {
337 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
338 append_binary_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
339 output,
340 ($cast)(value),
341 );
342 }
343 }
344
345 impl EncodeOctal for $type {
346 #[inline]
347 unsafe fn decode_append_octal<const ALTERNATE: bool>(
348 buffer: *const u8,
349 offset: &mut usize,
350 output: &mut Vec<u8>,
351 ) {
352 let value = ($read)(buffer, offset);
353 append_octal_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
354 output,
355 ($cast)(value),
356 );
357 }
358
359 #[inline]
360 unsafe fn decode_append_octal_at_offset<const ALTERNATE: bool>(
361 buffer: *const u8,
362 offset: usize,
363 output: &mut Vec<u8>,
364 ) {
365 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
366 append_octal_u64_padded_const::<b' ', { FORMAT_ALIGN_NONE }, 0, false, ALTERNATE>(
367 output,
368 ($cast)(value),
369 );
370 }
371 }
372 };
373}
374
375impl_signed_integer_format_traits!(
376 i32,
377 |buffer: *const u8, offset: &mut usize| {
378 let value = unsafe { buffer.add(*offset).cast::<i32>().read_unaligned() };
379 *offset += std::mem::size_of::<i32>();
380 value
381 },
382 |value: i32| (value as u32) as u64
383);
384impl_unsigned_integer_format_traits!(u32, |buffer: *const u8, offset: &mut usize| {
385 let value = unsafe { buffer.add(*offset).cast::<u32>().read_unaligned() };
386 *offset += std::mem::size_of::<u32>();
387 value
388});
389impl_signed_integer_format_traits!(
390 i64,
391 |buffer: *const u8, offset: &mut usize| {
392 let value = unsafe { buffer.add(*offset).cast::<i64>().read_unaligned() };
393 *offset += std::mem::size_of::<i64>();
394 value
395 },
396 |value: i64| value as u64
397);
398impl_unsigned_integer_format_traits!(u64, |buffer: *const u8, offset: &mut usize| {
399 let value = unsafe { buffer.add(*offset).cast::<u64>().read_unaligned() };
400 *offset += std::mem::size_of::<u64>();
401 value
402});
403impl_unsigned_integer_format_traits!(usize, |buffer: *const u8, offset: &mut usize| {
404 let value = unsafe { buffer.add(*offset).cast::<usize>().read_unaligned() };
405 *offset += std::mem::size_of::<usize>();
406 value
407});
408impl_signed_integer_format_traits!(
409 isize,
410 |buffer: *const u8, offset: &mut usize| {
411 let value = unsafe { buffer.add(*offset).cast::<isize>().read_unaligned() };
412 *offset += std::mem::size_of::<isize>();
413 value
414 },
415 |value: isize| (value as usize) as u64
416);
417
418impl Encode for i8 {
420 const ENCODED_SIZE_HINT: usize = 1;
421
422 #[inline(always)]
423 fn encoded_size(&self) -> usize {
424 1
425 }
426
427 #[inline(always)]
428 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
429 unsafe {
430 *buffer.add(*offset) = *self as u8;
431 }
432 *offset += 1;
433 }
434
435 #[inline(always)]
436 unsafe fn encode_at_offset(&self, buffer: *mut u8, offset: usize) {
437 unsafe {
438 *buffer.add(offset) = *self as u8;
439 }
440 }
441
442 #[inline]
443 unsafe fn decode_and_format(
444 buffer: *const u8,
445 offset: &mut usize,
446 output: &mut Vec<u8>,
447 format_spec: &str,
448 ) {
449 let value = unsafe { *buffer.add(*offset) } as i8;
450 *offset += 1;
451 if format_spec.is_empty() {
452 number_format::append_i32(output, value as i32);
453 } else {
454 append_integer_with_spec_cast(
455 output,
456 value,
457 (value as u8) as u64,
458 format_spec,
459 |output, spec| append_i32_decimal_with_spec(output, value as i32, spec),
460 );
461 }
462 }
463}
464unsafe impl EncodeFast for i8 {}
465
466impl_signed_integer_format_traits!(
467 i8,
468 |buffer: *const u8, offset: &mut usize| {
469 let value = unsafe { *buffer.add(*offset) } as i8;
470 *offset += 1;
471 value
472 },
473 |value: i8| (value as u8) as u64
474);
475
476impl Encode for u8 {
477 const ENCODED_SIZE_HINT: usize = 1;
478
479 #[inline(always)]
480 fn encoded_size(&self) -> usize {
481 1
482 }
483
484 #[inline(always)]
485 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
486 unsafe {
487 *buffer.add(*offset) = *self;
488 }
489 *offset += 1;
490 }
491
492 #[inline(always)]
493 unsafe fn encode_at_offset(&self, buffer: *mut u8, offset: usize) {
494 unsafe {
495 *buffer.add(offset) = *self;
496 }
497 }
498
499 #[inline]
500 unsafe fn decode_and_format(
501 buffer: *const u8,
502 offset: &mut usize,
503 output: &mut Vec<u8>,
504 format_spec: &str,
505 ) {
506 let value = unsafe { *buffer.add(*offset) };
507 *offset += 1;
508 if format_spec.is_empty() {
509 number_format::append_u32(output, value as u32);
510 } else {
511 append_integer_with_spec_cast(
512 output,
513 value,
514 value as u64,
515 format_spec,
516 |output, spec| append_u32_decimal_with_spec(output, value as u32, spec),
517 );
518 }
519 }
520}
521unsafe impl EncodeFast for u8 {}
522
523impl_unsigned_integer_format_traits!(u8, |buffer: *const u8, offset: &mut usize| {
524 let value = unsafe { *buffer.add(*offset) };
525 *offset += 1;
526 value
527});
528
529impl Encode for i16 {
530 const ENCODED_SIZE_HINT: usize = 2;
531
532 #[inline(always)]
533 fn encoded_size(&self) -> usize {
534 2
535 }
536
537 #[inline(always)]
538 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
539 unsafe {
540 buffer.add(*offset).cast::<i16>().write_unaligned(*self);
541 }
542 *offset += 2;
543 }
544
545 #[inline(always)]
546 unsafe fn encode_at_offset(&self, buffer: *mut u8, offset: usize) {
547 unsafe {
548 buffer.add(offset).cast::<i16>().write_unaligned(*self);
549 }
550 }
551
552 #[inline]
553 unsafe fn decode_and_format(
554 buffer: *const u8,
555 offset: &mut usize,
556 output: &mut Vec<u8>,
557 format_spec: &str,
558 ) {
559 let value = unsafe { buffer.add(*offset).cast::<i16>().read_unaligned() };
560 *offset += 2;
561 if format_spec.is_empty() {
562 number_format::append_i32(output, value as i32);
563 } else {
564 append_integer_with_spec_cast(
565 output,
566 value,
567 (value as u16) as u64,
568 format_spec,
569 |output, spec| append_i32_decimal_with_spec(output, value as i32, spec),
570 );
571 }
572 }
573}
574unsafe impl EncodeFast for i16 {}
575
576impl_signed_integer_format_traits!(
577 i16,
578 |buffer: *const u8, offset: &mut usize| {
579 let value = unsafe { buffer.add(*offset).cast::<i16>().read_unaligned() };
580 *offset += 2;
581 value
582 },
583 |value: i16| (value as u16) as u64
584);
585
586impl Encode for u16 {
587 const ENCODED_SIZE_HINT: usize = 2;
588
589 #[inline(always)]
590 fn encoded_size(&self) -> usize {
591 2
592 }
593
594 #[inline(always)]
595 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
596 unsafe {
597 buffer.add(*offset).cast::<u16>().write_unaligned(*self);
598 }
599 *offset += 2;
600 }
601
602 #[inline(always)]
603 unsafe fn encode_at_offset(&self, buffer: *mut u8, offset: usize) {
604 unsafe {
605 buffer.add(offset).cast::<u16>().write_unaligned(*self);
606 }
607 }
608
609 #[inline]
610 unsafe fn decode_and_format(
611 buffer: *const u8,
612 offset: &mut usize,
613 output: &mut Vec<u8>,
614 format_spec: &str,
615 ) {
616 let value = unsafe { buffer.add(*offset).cast::<u16>().read_unaligned() };
617 *offset += 2;
618 if format_spec.is_empty() {
619 number_format::append_u32(output, value as u32);
620 } else {
621 append_integer_with_spec_cast(
622 output,
623 value,
624 value as u64,
625 format_spec,
626 |output, spec| append_u32_decimal_with_spec(output, value as u32, spec),
627 );
628 }
629 }
630}
631unsafe impl EncodeFast for u16 {}
632
633impl_unsigned_integer_format_traits!(u16, |buffer: *const u8, offset: &mut usize| {
634 let value = unsafe { buffer.add(*offset).cast::<u16>().read_unaligned() };
635 *offset += 2;
636 value
637});
638
639macro_rules! impl_const_default_integer_format {
640 ($type:ty, $cast:expr, $append:ident) => {
641 impl EncodeConstDefaultFormat for $type {
642 #[inline]
643 unsafe fn decode_append_default_format<
644 const FILL: u8,
645 const ALIGN: u8,
646 const WIDTH: usize,
647 const PRECISION: usize,
648 const ZERO_PAD: bool,
649 >(
650 buffer: *const u8,
651 offset: &mut usize,
652 output: &mut Vec<u8>,
653 ) {
654 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
655 *offset += std::mem::size_of::<$type>();
656 let _ = PRECISION;
657 number_format::$append::<FILL, ALIGN, WIDTH, ZERO_PAD>(output, ($cast)(value));
658 }
659
660 #[inline]
661 unsafe fn decode_append_default_format_at_offset<
662 const FILL: u8,
663 const ALIGN: u8,
664 const WIDTH: usize,
665 const PRECISION: usize,
666 const ZERO_PAD: bool,
667 >(
668 buffer: *const u8,
669 offset: usize,
670 output: &mut Vec<u8>,
671 ) {
672 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
673 let _ = PRECISION;
674 number_format::$append::<FILL, ALIGN, WIDTH, ZERO_PAD>(output, ($cast)(value));
675 }
676 }
677 };
678}
679
680impl_const_default_integer_format!(i32, |value: i32| value, append_i32_padded_const);
681impl_const_default_integer_format!(u32, |value: u32| value, append_u32_padded_const);
682impl_const_default_integer_format!(i64, |value: i64| value, append_i64_padded_const);
683impl_const_default_integer_format!(u64, |value: u64| value, append_u64_padded_const);
684impl_const_default_integer_format!(usize, |value: usize| value as u64, append_u64_padded_const);
685impl_const_default_integer_format!(isize, |value: isize| value as i64, append_i64_padded_const);
686impl_const_default_integer_format!(i8, |value: i8| value as i32, append_i32_padded_const);
687impl_const_default_integer_format!(u8, |value: u8| value as u32, append_u32_padded_const);
688impl_const_default_integer_format!(i16, |value: i16| value as i32, append_i32_padded_const);
689impl_const_default_integer_format!(u16, |value: u16| value as u32, append_u32_padded_const);
690
691macro_rules! impl_const_typed_unsigned_integer_format_traits {
692 ($type:ty, $cast:expr) => {
693 impl EncodeConstLowerHexFormat for $type {
694 #[inline]
695 unsafe fn decode_append_lower_hex_format<
696 const FILL: u8,
697 const ALIGN: u8,
698 const WIDTH: usize,
699 const ZERO_PAD: bool,
700 const ALTERNATE: bool,
701 >(
702 buffer: *const u8,
703 offset: &mut usize,
704 output: &mut Vec<u8>,
705 ) {
706 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
707 *offset += std::mem::size_of::<$type>();
708 append_lower_hex_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
709 output,
710 ($cast)(value),
711 );
712 }
713
714 #[inline]
715 unsafe fn decode_append_lower_hex_format_at_offset<
716 const FILL: u8,
717 const ALIGN: u8,
718 const WIDTH: usize,
719 const ZERO_PAD: bool,
720 const ALTERNATE: bool,
721 >(
722 buffer: *const u8,
723 offset: usize,
724 output: &mut Vec<u8>,
725 ) {
726 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
727 append_lower_hex_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
728 output,
729 ($cast)(value),
730 );
731 }
732 }
733
734 impl EncodeConstUpperHexFormat for $type {
735 #[inline]
736 unsafe fn decode_append_upper_hex_format<
737 const FILL: u8,
738 const ALIGN: u8,
739 const WIDTH: usize,
740 const ZERO_PAD: bool,
741 const ALTERNATE: bool,
742 >(
743 buffer: *const u8,
744 offset: &mut usize,
745 output: &mut Vec<u8>,
746 ) {
747 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
748 *offset += std::mem::size_of::<$type>();
749 append_upper_hex_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
750 output,
751 ($cast)(value),
752 );
753 }
754
755 #[inline]
756 unsafe fn decode_append_upper_hex_format_at_offset<
757 const FILL: u8,
758 const ALIGN: u8,
759 const WIDTH: usize,
760 const ZERO_PAD: bool,
761 const ALTERNATE: bool,
762 >(
763 buffer: *const u8,
764 offset: usize,
765 output: &mut Vec<u8>,
766 ) {
767 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
768 append_upper_hex_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
769 output,
770 ($cast)(value),
771 );
772 }
773 }
774
775 impl EncodeConstBinaryFormat for $type {
776 #[inline]
777 unsafe fn decode_append_binary_format<
778 const FILL: u8,
779 const ALIGN: u8,
780 const WIDTH: usize,
781 const ZERO_PAD: bool,
782 const ALTERNATE: bool,
783 >(
784 buffer: *const u8,
785 offset: &mut usize,
786 output: &mut Vec<u8>,
787 ) {
788 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
789 *offset += std::mem::size_of::<$type>();
790 append_binary_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
791 output,
792 ($cast)(value),
793 );
794 }
795
796 #[inline]
797 unsafe fn decode_append_binary_format_at_offset<
798 const FILL: u8,
799 const ALIGN: u8,
800 const WIDTH: usize,
801 const ZERO_PAD: bool,
802 const ALTERNATE: bool,
803 >(
804 buffer: *const u8,
805 offset: usize,
806 output: &mut Vec<u8>,
807 ) {
808 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
809 append_binary_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
810 output,
811 ($cast)(value),
812 );
813 }
814 }
815
816 impl EncodeConstOctalFormat for $type {
817 #[inline]
818 unsafe fn decode_append_octal_format<
819 const FILL: u8,
820 const ALIGN: u8,
821 const WIDTH: usize,
822 const ZERO_PAD: bool,
823 const ALTERNATE: bool,
824 >(
825 buffer: *const u8,
826 offset: &mut usize,
827 output: &mut Vec<u8>,
828 ) {
829 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
830 *offset += std::mem::size_of::<$type>();
831 append_octal_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
832 output,
833 ($cast)(value),
834 );
835 }
836
837 #[inline]
838 unsafe fn decode_append_octal_format_at_offset<
839 const FILL: u8,
840 const ALIGN: u8,
841 const WIDTH: usize,
842 const ZERO_PAD: bool,
843 const ALTERNATE: bool,
844 >(
845 buffer: *const u8,
846 offset: usize,
847 output: &mut Vec<u8>,
848 ) {
849 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
850 append_octal_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
851 output,
852 ($cast)(value),
853 );
854 }
855 }
856 };
857}
858
859macro_rules! impl_const_typed_signed_integer_format_traits {
860 ($type:ty, $cast:expr) => {
861 impl EncodeConstLowerHexFormat for $type {
862 #[inline]
863 unsafe fn decode_append_lower_hex_format<
864 const FILL: u8,
865 const ALIGN: u8,
866 const WIDTH: usize,
867 const ZERO_PAD: bool,
868 const ALTERNATE: bool,
869 >(
870 buffer: *const u8,
871 offset: &mut usize,
872 output: &mut Vec<u8>,
873 ) {
874 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
875 *offset += std::mem::size_of::<$type>();
876 append_lower_hex_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
877 output,
878 ($cast)(value),
879 );
880 }
881
882 #[inline]
883 unsafe fn decode_append_lower_hex_format_at_offset<
884 const FILL: u8,
885 const ALIGN: u8,
886 const WIDTH: usize,
887 const ZERO_PAD: bool,
888 const ALTERNATE: bool,
889 >(
890 buffer: *const u8,
891 offset: usize,
892 output: &mut Vec<u8>,
893 ) {
894 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
895 append_lower_hex_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
896 output,
897 ($cast)(value),
898 );
899 }
900 }
901
902 impl EncodeConstUpperHexFormat for $type {
903 #[inline]
904 unsafe fn decode_append_upper_hex_format<
905 const FILL: u8,
906 const ALIGN: u8,
907 const WIDTH: usize,
908 const ZERO_PAD: bool,
909 const ALTERNATE: bool,
910 >(
911 buffer: *const u8,
912 offset: &mut usize,
913 output: &mut Vec<u8>,
914 ) {
915 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
916 *offset += std::mem::size_of::<$type>();
917 append_upper_hex_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
918 output,
919 ($cast)(value),
920 );
921 }
922
923 #[inline]
924 unsafe fn decode_append_upper_hex_format_at_offset<
925 const FILL: u8,
926 const ALIGN: u8,
927 const WIDTH: usize,
928 const ZERO_PAD: bool,
929 const ALTERNATE: bool,
930 >(
931 buffer: *const u8,
932 offset: usize,
933 output: &mut Vec<u8>,
934 ) {
935 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
936 append_upper_hex_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
937 output,
938 ($cast)(value),
939 );
940 }
941 }
942
943 impl EncodeConstBinaryFormat for $type {
944 #[inline]
945 unsafe fn decode_append_binary_format<
946 const FILL: u8,
947 const ALIGN: u8,
948 const WIDTH: usize,
949 const ZERO_PAD: bool,
950 const ALTERNATE: bool,
951 >(
952 buffer: *const u8,
953 offset: &mut usize,
954 output: &mut Vec<u8>,
955 ) {
956 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
957 *offset += std::mem::size_of::<$type>();
958 append_binary_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
959 output,
960 ($cast)(value),
961 );
962 }
963
964 #[inline]
965 unsafe fn decode_append_binary_format_at_offset<
966 const FILL: u8,
967 const ALIGN: u8,
968 const WIDTH: usize,
969 const ZERO_PAD: bool,
970 const ALTERNATE: bool,
971 >(
972 buffer: *const u8,
973 offset: usize,
974 output: &mut Vec<u8>,
975 ) {
976 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
977 append_binary_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
978 output,
979 ($cast)(value),
980 );
981 }
982 }
983
984 impl EncodeConstOctalFormat for $type {
985 #[inline]
986 unsafe fn decode_append_octal_format<
987 const FILL: u8,
988 const ALIGN: u8,
989 const WIDTH: usize,
990 const ZERO_PAD: bool,
991 const ALTERNATE: bool,
992 >(
993 buffer: *const u8,
994 offset: &mut usize,
995 output: &mut Vec<u8>,
996 ) {
997 let value = unsafe { buffer.add(*offset).cast::<$type>().read_unaligned() };
998 *offset += std::mem::size_of::<$type>();
999 append_octal_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
1000 output,
1001 ($cast)(value),
1002 );
1003 }
1004
1005 #[inline]
1006 unsafe fn decode_append_octal_format_at_offset<
1007 const FILL: u8,
1008 const ALIGN: u8,
1009 const WIDTH: usize,
1010 const ZERO_PAD: bool,
1011 const ALTERNATE: bool,
1012 >(
1013 buffer: *const u8,
1014 offset: usize,
1015 output: &mut Vec<u8>,
1016 ) {
1017 let value = unsafe { buffer.add(offset).cast::<$type>().read_unaligned() };
1018 append_octal_u64_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, ALTERNATE>(
1019 output,
1020 ($cast)(value),
1021 );
1022 }
1023 }
1024 };
1025}
1026
1027impl_const_typed_signed_integer_format_traits!(i32, |value: i32| (value as u32) as u64);
1028impl_const_typed_unsigned_integer_format_traits!(u32, |value: u32| value as u64);
1029impl_const_typed_signed_integer_format_traits!(i64, |value: i64| value as u64);
1030impl_const_typed_unsigned_integer_format_traits!(u64, |value: u64| value);
1031impl_const_typed_unsigned_integer_format_traits!(usize, |value: usize| value as u64);
1032impl_const_typed_signed_integer_format_traits!(isize, |value: isize| (value as usize) as u64);
1033impl_const_typed_signed_integer_format_traits!(i8, |value: i8| (value as u8) as u64);
1034impl_const_typed_unsigned_integer_format_traits!(u8, |value: u8| value as u64);
1035impl_const_typed_signed_integer_format_traits!(i16, |value: i16| (value as u16) as u64);
1036impl_const_typed_unsigned_integer_format_traits!(u16, |value: u16| value as u64);
1037
1038impl Encode for bool {
1039 const ENCODED_SIZE_HINT: usize = 1;
1040
1041 #[inline(always)]
1042 fn encoded_size(&self) -> usize {
1043 1
1044 }
1045
1046 #[inline(always)]
1047 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
1048 unsafe {
1049 *buffer.add(*offset) = *self as u8;
1050 }
1051 *offset += 1;
1052 }
1053
1054 #[inline(always)]
1055 unsafe fn encode_at_offset(&self, buffer: *mut u8, offset: usize) {
1056 unsafe {
1057 *buffer.add(offset) = *self as u8;
1058 }
1059 }
1060
1061 #[inline]
1062 unsafe fn decode_and_format(
1063 buffer: *const u8,
1064 offset: &mut usize,
1065 output: &mut Vec<u8>,
1066 format_spec: &str,
1067 ) {
1068 let value = unsafe { *buffer.add(*offset) } != 0;
1069 *offset += 1;
1070 if format_spec.is_empty() {
1071 number_format::append_bool(output, value);
1072 } else {
1073 append_display_with_spec(output, value, format_spec);
1074 }
1075 }
1076}
1077unsafe impl EncodeFast for bool {}
1078
1079impl Encode for f64 {
1080 const ENCODED_SIZE_HINT: usize = 8;
1081
1082 #[inline(always)]
1083 fn encoded_size(&self) -> usize {
1084 8
1085 }
1086
1087 #[inline(always)]
1088 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
1089 unsafe {
1090 buffer.add(*offset).cast::<f64>().write_unaligned(*self);
1091 }
1092 *offset += 8;
1093 }
1094
1095 #[inline(always)]
1096 unsafe fn encode_at_offset(&self, buffer: *mut u8, offset: usize) {
1097 unsafe {
1098 buffer.add(offset).cast::<f64>().write_unaligned(*self);
1099 }
1100 }
1101
1102 #[inline]
1103 unsafe fn decode_and_format(
1104 buffer: *const u8,
1105 offset: &mut usize,
1106 output: &mut Vec<u8>,
1107 format_spec: &str,
1108 ) {
1109 let value = unsafe { buffer.add(*offset).cast::<f64>().read_unaligned() };
1110 *offset += 8;
1111 if format_spec.is_empty() {
1112 append_ryu_float(output, value);
1113 } else {
1114 append_float_with_spec(output, value, format_spec);
1115 }
1116 }
1117}
1118unsafe impl EncodeFast for f64 {}
1119
1120impl EncodeConstDefaultFormat for f64 {
1121 #[inline]
1122 unsafe fn decode_append_default_format<
1123 const FILL: u8,
1124 const ALIGN: u8,
1125 const WIDTH: usize,
1126 const PRECISION: usize,
1127 const ZERO_PAD: bool,
1128 >(
1129 buffer: *const u8,
1130 offset: &mut usize,
1131 output: &mut Vec<u8>,
1132 ) {
1133 let value = unsafe { buffer.add(*offset).cast::<f64>().read_unaligned() };
1134 *offset += 8;
1135 let mut body = Vec::new();
1136 if PRECISION == FORMAT_PRECISION_NONE {
1137 append_ryu_float(&mut body, value);
1138 } else {
1139 let mut writer = VecWriter(&mut body);
1140 write!(writer, "{:.*}", PRECISION, value).unwrap();
1141 }
1142 append_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, { FORMAT_ALIGN_RIGHT }>(output, &body);
1143 }
1144}
1145
1146impl EncodeConstFloatFormat for f64 {
1147 #[inline]
1148 unsafe fn decode_append_float_format<
1149 const FILL: u8,
1150 const ALIGN: u8,
1151 const WIDTH: usize,
1152 const PRECISION: usize,
1153 const ZERO_PAD: bool,
1154 const TY: u8,
1155 >(
1156 buffer: *const u8,
1157 offset: &mut usize,
1158 output: &mut Vec<u8>,
1159 ) {
1160 let value = unsafe { buffer.add(*offset).cast::<f64>().read_unaligned() };
1161 *offset += 8;
1162 let mut body = Vec::new();
1163 append_const_float_body::<f64, PRECISION, TY>(&mut body, value);
1164 append_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, { FORMAT_ALIGN_RIGHT }>(output, &body);
1165 }
1166}
1167
1168impl Encode for f32 {
1169 const ENCODED_SIZE_HINT: usize = 4;
1170
1171 #[inline(always)]
1172 fn encoded_size(&self) -> usize {
1173 4
1174 }
1175
1176 #[inline(always)]
1177 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
1178 unsafe {
1179 buffer.add(*offset).cast::<f32>().write_unaligned(*self);
1180 }
1181 *offset += 4;
1182 }
1183
1184 #[inline(always)]
1185 unsafe fn encode_at_offset(&self, buffer: *mut u8, offset: usize) {
1186 unsafe {
1187 buffer.add(offset).cast::<f32>().write_unaligned(*self);
1188 }
1189 }
1190
1191 #[inline]
1192 unsafe fn decode_and_format(
1193 buffer: *const u8,
1194 offset: &mut usize,
1195 output: &mut Vec<u8>,
1196 format_spec: &str,
1197 ) {
1198 let value = unsafe { buffer.add(*offset).cast::<f32>().read_unaligned() };
1199 *offset += 4;
1200 if format_spec.is_empty() {
1201 append_ryu_float(output, value);
1202 } else {
1203 append_float_with_spec(output, value, format_spec);
1204 }
1205 }
1206}
1207unsafe impl EncodeFast for f32 {}
1208
1209impl EncodeConstDefaultFormat for f32 {
1210 #[inline]
1211 unsafe fn decode_append_default_format<
1212 const FILL: u8,
1213 const ALIGN: u8,
1214 const WIDTH: usize,
1215 const PRECISION: usize,
1216 const ZERO_PAD: bool,
1217 >(
1218 buffer: *const u8,
1219 offset: &mut usize,
1220 output: &mut Vec<u8>,
1221 ) {
1222 let value = unsafe { buffer.add(*offset).cast::<f32>().read_unaligned() };
1223 *offset += 4;
1224 let mut body = Vec::new();
1225 if PRECISION == FORMAT_PRECISION_NONE {
1226 append_ryu_float(&mut body, value);
1227 } else {
1228 let mut writer = VecWriter(&mut body);
1229 write!(writer, "{:.*}", PRECISION, value).unwrap();
1230 }
1231 append_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, { FORMAT_ALIGN_RIGHT }>(output, &body);
1232 }
1233}
1234
1235impl EncodeConstFloatFormat for f32 {
1236 #[inline]
1237 unsafe fn decode_append_float_format<
1238 const FILL: u8,
1239 const ALIGN: u8,
1240 const WIDTH: usize,
1241 const PRECISION: usize,
1242 const ZERO_PAD: bool,
1243 const TY: u8,
1244 >(
1245 buffer: *const u8,
1246 offset: &mut usize,
1247 output: &mut Vec<u8>,
1248 ) {
1249 let value = unsafe { buffer.add(*offset).cast::<f32>().read_unaligned() };
1250 *offset += 4;
1251 let mut body = Vec::new();
1252 append_const_float_body::<f32, PRECISION, TY>(&mut body, value);
1253 append_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, { FORMAT_ALIGN_RIGHT }>(output, &body);
1254 }
1255}