protobuf/reflect/message/
message_ref.rs

1use std::fmt;
2use std::ops::Deref;
3
4use crate::message_dyn::MessageDyn;
5use crate::reflect::dynamic::DynamicMessage;
6use crate::reflect::reflect_eq::ReflectEq;
7use crate::reflect::reflect_eq::ReflectEqMode;
8use crate::reflect::MessageDescriptor;
9use crate::MessageFull;
10
11#[derive(Clone, Debug)]
12enum 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)]
19pub struct MessageRef<'a> {
20    imp: MessageRefImpl<'a>,
21}
22
23impl<'a> fmt::Display for MessageRef<'a> {
24    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25        fmt::Display::fmt(self.deref(), f)
26    }
27}
28
29impl<'a> From<&'a dyn MessageDyn> for MessageRef<'a> {
30    fn from(m: &'a dyn MessageDyn) -> Self {
31        MessageRef {
32            imp: MessageRefImpl::Message(m),
33        }
34    }
35}
36
37impl<'a, M: MessageFull> From<&'a M> for MessageRef<'a> {
38    fn from(m: &'a M) -> Self {
39        MessageRef {
40            imp: MessageRefImpl::Message(m),
41        }
42    }
43}
44
45impl<'a> ReflectEq for MessageRef<'a> {
46    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
53impl<'a> MessageRef<'a> {
54    /// Wrap a message.
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.
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
74impl<'a> Deref for MessageRef<'a> {
75    type Target = dyn MessageDyn;
76
77    fn deref(&self) -> &dyn MessageDyn {
78        match &self.imp {
79            MessageRefImpl::Message(m) => *m,
80            MessageRefImpl::EmptyDynamic(e) => e,
81        }
82    }
83}