protobuf/
message_dyn.rs
1use std::any::Any;
2use std::any::TypeId;
3use std::fmt;
4use std::io::Write;
5
6use crate::coded_output_stream::with::WithCodedOutputStream;
7use crate::error::ProtobufError;
8use crate::reflect::MessageDescriptor;
9use crate::reflect::ReflectEqMode;
10use crate::wire_format::check_message_size;
11use crate::CodedInputStream;
12use crate::CodedOutputStream;
13use crate::MessageFull;
14use crate::SpecialFields;
15use crate::UnknownFields;
16
17pub trait MessageDyn: Any + fmt::Debug + fmt::Display + Send + Sync + 'static {
23 fn descriptor_dyn(&self) -> MessageDescriptor;
25
26 fn merge_from_dyn(&mut self, is: &mut CodedInputStream) -> crate::Result<()>;
28
29 fn write_to_with_cached_sizes_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()>;
31
32 fn compute_size_dyn(&self) -> u64;
34
35 fn is_initialized_dyn(&self) -> bool;
38
39 fn special_fields_dyn(&self) -> &SpecialFields;
41 fn mut_special_fields_dyn(&mut self) -> &mut SpecialFields;
43}
44
45impl<M: MessageFull> MessageDyn for M {
46 fn descriptor_dyn(&self) -> MessageDescriptor {
47 M::descriptor()
48 }
49
50 fn merge_from_dyn(&mut self, is: &mut CodedInputStream) -> crate::Result<()> {
51 self.merge_from(is)
52 }
53
54 fn write_to_with_cached_sizes_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()> {
55 self.write_to_with_cached_sizes(os)
56 }
57
58 fn compute_size_dyn(&self) -> u64 {
59 self.compute_size()
60 }
61
62 fn is_initialized_dyn(&self) -> bool {
63 self.is_initialized()
64 }
65
66 fn special_fields_dyn(&self) -> &SpecialFields {
67 self.special_fields()
68 }
69
70 fn mut_special_fields_dyn(&mut self) -> &mut SpecialFields {
71 self.mut_special_fields()
72 }
73}
74
75impl dyn MessageDyn {
76 pub fn check_initialized_dyn(&self) -> crate::Result<()> {
78 if !self.is_initialized_dyn() {
79 Err(
80 ProtobufError::MessageNotInitialized(self.descriptor_dyn().name().to_owned())
81 .into(),
82 )
83 } else {
84 Ok(())
85 }
86 }
87
88 pub fn write_to_writer_dyn(&self, w: &mut dyn Write) -> crate::Result<()> {
90 w.with_coded_output_stream(|os| self.write_to_dyn(os))
91 }
92
93 pub fn write_to_vec_dyn(&self, v: &mut Vec<u8>) -> crate::Result<()> {
95 v.with_coded_output_stream(|os| self.write_to_dyn(os))
96 }
97
98 pub fn write_to_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()> {
102 self.check_initialized_dyn()?;
103
104 let size = self.compute_size_dyn();
106 let size = check_message_size(size)?;
107 os.reserve_additional(size, self.descriptor_dyn().name())?;
108 self.write_to_with_cached_sizes_dyn(os)?;
109
110 Ok(())
111 }
112
113 pub fn write_length_delimited_to_vec_dyn(&self, vec: &mut Vec<u8>) -> crate::Result<()> {
116 let mut os = CodedOutputStream::vec(vec);
117 self.write_length_delimited_to_dyn(&mut os)?;
118 os.flush()?;
119 Ok(())
120 }
121
122 pub fn merge_from_bytes_dyn(&mut self, bytes: &[u8]) -> crate::Result<()> {
124 let mut is = CodedInputStream::from_bytes(bytes);
125 self.merge_from_dyn(&mut is)
126 }
127
128 pub fn write_to_bytes_dyn(&self) -> crate::Result<Vec<u8>> {
133 self.check_initialized_dyn()?;
134
135 let size = self.compute_size_dyn();
136 let size = check_message_size(size)?;
137 let mut v = Vec::new();
138 let mut os = CodedOutputStream::vec(&mut v);
139 os.reserve_additional(size, self.descriptor_dyn().name())?;
140 self.write_to_with_cached_sizes_dyn(&mut os)?;
141 os.flush()?;
142 drop(os);
143 Ok(v)
144 }
145
146 pub fn write_length_delimited_to_dyn(&self, os: &mut CodedOutputStream) -> crate::Result<()> {
149 let size = self.compute_size_dyn();
150 let size = check_message_size(size)?;
151 os.reserve_additional_for_length_delimited(size, self.descriptor_dyn().name())?;
152 os.write_raw_varint32(size)?;
153
154 let pos = os.total_bytes_written();
155
156 self.write_to_with_cached_sizes_dyn(os)?;
157
158 assert_eq!(os.total_bytes_written() - pos, size as u64);
160
161 Ok(())
162 }
163
164 pub fn write_length_delimited_to_writer_dyn(&self, w: &mut dyn Write) -> crate::Result<()> {
167 w.with_coded_output_stream(|os| self.write_length_delimited_to_dyn(os))
168 }
169
170 pub fn write_length_delimited_to_bytes_dyn(&self) -> crate::Result<Vec<u8>> {
173 let mut v = Vec::new();
174 v.with_coded_output_stream(|os| self.write_length_delimited_to_dyn(os))?;
175 Ok(v)
176 }
177
178 pub fn unknown_fields_dyn(&self) -> &UnknownFields {
180 self.special_fields_dyn().unknown_fields()
181 }
182 pub fn mut_unknown_fields_dyn(&mut self) -> &mut UnknownFields {
184 self.mut_special_fields_dyn().mut_unknown_fields()
185 }
186
187 pub fn downcast_box<T: Any>(
197 self: Box<dyn MessageDyn>,
198 ) -> std::result::Result<Box<T>, Box<dyn MessageDyn>> {
199 if Any::type_id(&*self) == TypeId::of::<T>() {
200 unsafe {
201 let raw: *mut dyn MessageDyn = Box::into_raw(self);
202 Ok(Box::from_raw(raw as *mut T))
203 }
204 } else {
205 Err(self)
206 }
207 }
208
209 pub fn downcast_ref<'a, M: MessageFull + 'a>(&'a self) -> Option<&'a M> {
219 if Any::type_id(&*self) == TypeId::of::<M>() {
220 unsafe { Some(&*(self as *const dyn MessageDyn as *const M)) }
221 } else {
222 None
223 }
224 }
225
226 pub fn downcast_mut<'a, M: MessageFull + 'a>(&'a mut self) -> Option<&'a mut M> {
236 if Any::type_id(&*self) == TypeId::of::<M>() {
237 unsafe { Some(&mut *(self as *mut dyn MessageDyn as *mut M)) }
238 } else {
239 None
240 }
241 }
242
243 pub fn clone_box(&self) -> Box<dyn MessageDyn> {
245 self.descriptor_dyn().clone_message(self)
246 }
247
248 pub fn reflect_eq_dyn(&self, other: &dyn MessageDyn, mode: &ReflectEqMode) -> bool {
250 MessageDescriptor::reflect_eq_maybe_unrelated(self, other, mode)
251 }
252}
253
254impl Clone for Box<dyn MessageDyn> {
255 fn clone(&self) -> Self {
256 (*self).clone_box()
257 }
258}
259
260impl PartialEq for Box<dyn MessageDyn> {
261 fn eq(&self, other: &Box<dyn MessageDyn>) -> bool {
262 MessageDescriptor::reflect_eq_maybe_unrelated(&**self, &**other, &ReflectEqMode::default())
263 }
264}
265
266#[cfg(test)]
267mod test {
268 use crate::descriptor::FileDescriptorProto;
269 use crate::MessageDyn;
270
271 #[test]
272 fn downcast_ref() {
273 let m = FileDescriptorProto::new();
274 let d = &m as &dyn MessageDyn;
275 let c: &FileDescriptorProto = d.downcast_ref().unwrap();
276 assert_eq!(
277 c as *const FileDescriptorProto,
278 &m as *const FileDescriptorProto
279 );
280 }
281
282 #[test]
283 fn downcast_mut() {
284 let mut m = FileDescriptorProto::new();
285 let d = &mut m as &mut dyn MessageDyn;
286 let c: &mut FileDescriptorProto = d.downcast_mut().unwrap();
287 assert_eq!(
288 c as *const FileDescriptorProto,
289 &m as *const FileDescriptorProto
290 );
291 }
292
293 #[test]
294 fn downcast_box() {
295 let m = FileDescriptorProto::new();
296 let d: Box<dyn MessageDyn> = Box::new(m);
297 let mut _c: Box<FileDescriptorProto> = d.downcast_box().unwrap();
298 }
299}