• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::fmt;
2 use std::ops::Deref;
3 
4 use crate::message_dyn::MessageDyn;
5 use crate::reflect::dynamic::DynamicMessage;
6 use crate::reflect::reflect_eq::ReflectEq;
7 use crate::reflect::reflect_eq::ReflectEqMode;
8 use crate::reflect::MessageDescriptor;
9 use crate::MessageFull;
10 
11 #[derive(Clone, Debug)]
12 enum MessageRefImpl<'a> {
13     Message(&'a dyn MessageDyn),
14     EmptyDynamic(DynamicMessage),
15 }
16 
17 /// Wrapper around either [`MessageFull`] reference or a container for an empty dynamic message.
18 #[derive(Clone, Debug)]
19 pub struct MessageRef<'a> {
20     imp: MessageRefImpl<'a>,
21 }
22 
23 impl<'a> fmt::Display for MessageRef<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result24     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25         fmt::Display::fmt(self.deref(), f)
26     }
27 }
28 
29 impl<'a> From<&'a dyn MessageDyn> for MessageRef<'a> {
from(m: &'a dyn MessageDyn) -> Self30     fn from(m: &'a dyn MessageDyn) -> Self {
31         MessageRef {
32             imp: MessageRefImpl::Message(m),
33         }
34     }
35 }
36 
37 impl<'a, M: MessageFull> From<&'a M> for MessageRef<'a> {
from(m: &'a M) -> Self38     fn from(m: &'a M) -> Self {
39         MessageRef {
40             imp: MessageRefImpl::Message(m),
41         }
42     }
43 }
44 
45 impl<'a> ReflectEq for MessageRef<'a> {
reflect_eq(&self, that: &Self, mode: &ReflectEqMode) -> bool46     fn reflect_eq(&self, that: &Self, mode: &ReflectEqMode) -> bool {
47         let ad = self.descriptor_dyn();
48         let bd = that.descriptor_dyn();
49         ad == bd && ad.reflect_eq(&**self, &**that, mode)
50     }
51 }
52 
53 impl<'a> MessageRef<'a> {
54     /// Wrap a message.
new(message: &'a dyn MessageDyn) -> MessageRef<'a>55     pub fn new(message: &'a dyn MessageDyn) -> MessageRef<'a> {
56         MessageRef {
57             imp: MessageRefImpl::Message(message),
58         }
59     }
60 
61     /// Default (empty) instance of given message type.
default_instance(message: &MessageDescriptor) -> MessageRef<'static>62     pub fn default_instance(message: &MessageDescriptor) -> MessageRef<'static> {
63         // Note we create a native generated instance for generated types
64         // and dynamic message for dynamic types.
65         match message.default_instance() {
66             Some(m) => MessageRef::new(m),
67             None => MessageRef {
68                 imp: MessageRefImpl::EmptyDynamic(DynamicMessage::new(message.clone())),
69             },
70         }
71     }
72 }
73 
74 impl<'a> Deref for MessageRef<'a> {
75     type Target = dyn MessageDyn;
76 
deref(&self) -> &dyn MessageDyn77     fn deref(&self) -> &dyn MessageDyn {
78         match &self.imp {
79             MessageRefImpl::Message(m) => *m,
80             MessageRefImpl::EmptyDynamic(e) => e,
81         }
82     }
83 }
84