mesh_protobuf/
transparent.rs1use crate::FieldDecode;
7use crate::FieldEncode;
8use crate::MessageDecode;
9use crate::MessageEncode;
10use crate::Result;
11use crate::inplace::InplaceOption;
12use crate::protobuf::FieldReader;
13use crate::protobuf::FieldSizer;
14use crate::protobuf::FieldWriter;
15use crate::protobuf::MessageReader;
16use crate::protobuf::MessageSizer;
17use crate::protobuf::MessageWriter;
18use crate::protofile::DescribeField;
19use crate::protofile::DescribeMessage;
20use crate::protofile::FieldType;
21use crate::protofile::MessageDescription;
22use crate::table::decode::DecoderEntry;
23use crate::table::encode::EncoderEntry;
24use core::mem::MaybeUninit;
25use core::ptr;
26
27pub unsafe trait Transparent {
34 type Inner;
36 const OFFSET: usize;
39}
40
41#[derive(Copy, Clone)]
44pub struct TransparentEncoding<E>(E);
45
46impl<T: Transparent, E: DescribeField<T::Inner>> DescribeField<T> for TransparentEncoding<E> {
47 const FIELD_TYPE: FieldType<'static> = E::FIELD_TYPE;
48 const PACKED_TYPE: Option<&'static str> = E::PACKED_TYPE;
49}
50
51impl<T: Transparent, E: DescribeMessage<T::Inner>> DescribeMessage<T> for TransparentEncoding<E> {
52 const DESCRIPTION: MessageDescription<'static> = E::DESCRIPTION;
53}
54
55impl<T: Transparent, E: MessageEncode<T::Inner, R>, R> MessageEncode<T, R>
56 for TransparentEncoding<E>
57{
58 fn write_message(item: T, writer: MessageWriter<'_, '_, R>) {
59 let item = MaybeUninit::new(item);
60 let inner = unsafe { item.as_ptr().byte_add(T::OFFSET).cast::<T::Inner>().read() };
63 E::write_message(inner, writer)
64 }
65
66 fn compute_message_size(item: &mut T, sizer: MessageSizer<'_>) {
67 let inner = unsafe { &mut *ptr::from_mut(item).byte_add(T::OFFSET).cast::<T::Inner>() };
70 E::compute_message_size(inner, sizer)
71 }
72}
73
74impl<'de, T: Transparent, E: MessageDecode<'de, T::Inner, R>, R> MessageDecode<'de, T, R>
75 for TransparentEncoding<E>
76{
77 fn read_message(
78 item: &mut InplaceOption<'_, T>,
79 reader: MessageReader<'de, '_, R>,
80 ) -> Result<()> {
81 let init = item.forget();
82 let inner = unsafe {
85 &mut *item
86 .as_mut_ptr()
87 .byte_add(T::OFFSET)
88 .cast::<MaybeUninit<T::Inner>>()
89 };
90 let mut inner = if init {
91 unsafe { InplaceOption::new_init_unchecked(inner) }
93 } else {
94 InplaceOption::uninit(inner)
95 };
96 let r = E::read_message(&mut inner, reader);
97 if inner.forget() {
98 unsafe { item.set_init_unchecked() };
101 }
102 r
103 }
104}
105
106impl<T: Transparent, E: FieldEncode<T::Inner, R>, R> FieldEncode<T, R> for TransparentEncoding<E> {
107 fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
108 let item = MaybeUninit::new(item);
109 let inner = unsafe { item.as_ptr().byte_add(T::OFFSET).cast::<T::Inner>().read() };
112 E::write_field(inner, writer)
113 }
114
115 fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
116 let inner = unsafe { &mut *ptr::from_mut(item).byte_add(T::OFFSET).cast::<T::Inner>() };
119 E::compute_field_size(inner, sizer)
120 }
121
122 fn wrap_in_sequence() -> bool {
123 E::wrap_in_sequence()
124 }
125
126 const ENTRY: EncoderEntry<T, R> = {
127 if T::OFFSET == 0 {
130 unsafe { EncoderEntry::new_unchecked(E::ENTRY.erase()) }
134 } else {
135 EncoderEntry::custom::<Self>()
138 }
139 };
140}
141
142impl<'de, T: Transparent, E: FieldDecode<'de, T::Inner, R>, R> FieldDecode<'de, T, R>
143 for TransparentEncoding<E>
144{
145 fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'de, '_, R>) -> Result<()> {
146 let init = item.forget();
147 let inner = unsafe {
150 &mut *item
151 .as_mut_ptr()
152 .byte_add(T::OFFSET)
153 .cast::<MaybeUninit<T::Inner>>()
154 };
155 let mut inner = if init {
156 unsafe { InplaceOption::new_init_unchecked(inner) }
158 } else {
159 InplaceOption::uninit(inner)
160 };
161 let r = E::read_field(&mut inner, reader);
162 if inner.forget() {
163 unsafe { item.set_init_unchecked() };
166 }
167 r
168 }
169
170 fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
171 let init = item.forget();
172 let inner = unsafe {
175 &mut *item
176 .as_mut_ptr()
177 .byte_add(T::OFFSET)
178 .cast::<MaybeUninit<T::Inner>>()
179 };
180 let mut inner = if init {
181 unsafe { InplaceOption::new_init_unchecked(inner) }
183 } else {
184 InplaceOption::uninit(inner)
185 };
186 let r = E::default_field(&mut inner);
187 if inner.forget() {
188 unsafe { item.set_init_unchecked() };
191 }
192 r
193 }
194
195 fn wrap_in_sequence() -> bool {
196 E::wrap_in_sequence()
197 }
198
199 const ENTRY: DecoderEntry<'de, T, R> = {
200 if T::OFFSET == 0 {
203 unsafe { DecoderEntry::new_unchecked(E::ENTRY.erase()) }
208 } else {
209 DecoderEntry::custom::<Self>()
212 }
213 };
214}