ferrilog_core/encode/
strings.rs1use super::{
2 Encode, EncodeFast, FORMAT_ALIGN_LEFT, FORMAT_PRECISION_NONE,
3 format::{append_padded_const, append_str_with_spec, truncate_to_boundary},
4 traits::EncodeConstDefaultFormat,
5};
6
7impl Encode for &str {
10 #[inline(always)]
11 fn encoded_size(&self) -> usize {
12 4 + self.len() }
14
15 #[inline(always)]
16 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
17 unsafe {
18 buffer.add(*offset).cast::<u32>().write_unaligned(self.len() as u32);
20 *offset += 4;
21 core::ptr::copy_nonoverlapping(self.as_ptr(), buffer.add(*offset), self.len());
23 }
24 *offset += self.len();
25 }
26
27 #[inline]
28 unsafe fn decode_and_format(
29 buffer: *const u8,
30 offset: &mut usize,
31 output: &mut Vec<u8>,
32 format_spec: &str,
33 ) {
34 unsafe {
35 let length = buffer.add(*offset).cast::<u32>().read_unaligned() as usize;
36 *offset += 4;
37 let value = core::str::from_utf8_unchecked(core::slice::from_raw_parts(
38 buffer.add(*offset),
39 length,
40 ));
41 if format_spec.is_empty() {
42 output.extend_from_slice(value.as_bytes());
43 } else {
44 append_str_with_spec(output, value, format_spec);
45 }
46 *offset += length;
47 }
48 }
49}
50unsafe impl EncodeFast for &str {}
51
52impl EncodeConstDefaultFormat for &str {
53 #[inline]
54 unsafe fn decode_append_default_format<
55 const FILL: u8,
56 const ALIGN: u8,
57 const WIDTH: usize,
58 const PRECISION: usize,
59 const ZERO_PAD: bool,
60 >(
61 buffer: *const u8,
62 offset: &mut usize,
63 output: &mut Vec<u8>,
64 ) {
65 let length = unsafe { buffer.add(*offset).cast::<u32>().read_unaligned() as usize };
66 *offset += 4;
67 let value = unsafe {
68 core::str::from_utf8_unchecked(core::slice::from_raw_parts(buffer.add(*offset), length))
69 };
70 let body = if PRECISION == FORMAT_PRECISION_NONE {
71 value
72 } else {
73 truncate_to_boundary(value, PRECISION)
74 };
75 append_padded_const::<FILL, ALIGN, WIDTH, ZERO_PAD, { FORMAT_ALIGN_LEFT }>(
76 output,
77 body.as_bytes(),
78 );
79 *offset += length;
80 }
81}
82
83impl Encode for String {
84 #[inline(always)]
85 fn encoded_size(&self) -> usize {
86 self.as_str().encoded_size()
87 }
88
89 #[inline(always)]
90 unsafe fn encode(&self, buffer: *mut u8, offset: &mut usize) {
91 unsafe {
92 self.as_str().encode(buffer, offset);
93 }
94 }
95
96 #[inline]
97 unsafe fn decode_and_format(
98 buffer: *const u8,
99 offset: &mut usize,
100 output: &mut Vec<u8>,
101 format_spec: &str,
102 ) {
103 unsafe {
104 <&str as Encode>::decode_and_format(buffer, offset, output, format_spec);
105 }
106 }
107}
108unsafe impl EncodeFast for String {}
109
110impl EncodeConstDefaultFormat for String {
111 #[inline]
112 unsafe fn decode_append_default_format<
113 const FILL: u8,
114 const ALIGN: u8,
115 const WIDTH: usize,
116 const PRECISION: usize,
117 const ZERO_PAD: bool,
118 >(
119 buffer: *const u8,
120 offset: &mut usize,
121 output: &mut Vec<u8>,
122 ) {
123 unsafe {
124 <&str as EncodeConstDefaultFormat>::decode_append_default_format::<
125 FILL,
126 ALIGN,
127 WIDTH,
128 PRECISION,
129 ZERO_PAD,
130 >(buffer, offset, output);
131 }
132 }
133}