protobuf/reflect/value/
value_ref.rs

1use std::fmt;
2use std::hash::Hash;
3use std::hash::Hasher;
4use std::mem;
5
6use crate::reflect::value::value_box::ReflectValueBox;
7use crate::reflect::EnumDescriptor;
8use crate::reflect::EnumValueDescriptor;
9use crate::reflect::MessageDescriptor;
10use crate::reflect::MessageRef;
11use crate::reflect::ProtobufValue;
12use crate::reflect::ReflectEq;
13use crate::reflect::ReflectEqMode;
14use crate::reflect::RuntimeType;
15use crate::MessageDyn;
16
17/// A reference to a value
18#[derive(Debug, Clone)]
19pub enum ReflectValueRef<'a> {
20    /// `u32`
21    U32(u32),
22    /// `u64`
23    U64(u64),
24    /// `i32`
25    I32(i32),
26    /// `i64`
27    I64(i64),
28    /// `f32`
29    F32(f32),
30    /// `f64`
31    F64(f64),
32    /// `bool`
33    Bool(bool),
34    /// `string`
35    String(&'a str),
36    /// `bytes`
37    Bytes(&'a [u8]),
38    /// `enum`
39    Enum(
40        EnumDescriptor,
41        /// Enum value.
42        ///
43        /// Note when `allow_alias` option is enabled, more than one enum variant
44        /// may have the same value.
45        i32,
46    ),
47    /// `message`
48    Message(MessageRef<'a>),
49}
50
51impl<'a> fmt::Display for ReflectValueRef<'a> {
52    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53        match self {
54            ReflectValueRef::U32(v) => write!(f, "{}", v),
55            ReflectValueRef::U64(v) => write!(f, "{}", v),
56            ReflectValueRef::I32(v) => write!(f, "{}", v),
57            ReflectValueRef::I64(v) => write!(f, "{}", v),
58            ReflectValueRef::F32(v) => write!(f, "{}", v),
59            ReflectValueRef::F64(v) => write!(f, "{}", v),
60            ReflectValueRef::Bool(v) => write!(f, "{}", v),
61            ReflectValueRef::String(v) => write!(f, "{}", v),
62            // TODO: better display
63            ReflectValueRef::Bytes(v) => write!(f, "{:?}", v),
64            ReflectValueRef::Enum(descriptor, value) => match descriptor.value_by_number(*value) {
65                Some(v) => write!(f, "{}", v.name()),
66                None => write!(f, "{}", value),
67            },
68            ReflectValueRef::Message(msg) => write!(f, "{}", msg),
69        }
70    }
71}
72
73impl<'a> ReflectValueRef<'a> {
74    /// Get type of this value.
75    pub fn get_type(&self) -> RuntimeType {
76        match self {
77            ReflectValueRef::U32(..) => RuntimeType::U32,
78            ReflectValueRef::U64(..) => RuntimeType::U64,
79            ReflectValueRef::I32(..) => RuntimeType::I32,
80            ReflectValueRef::I64(..) => RuntimeType::I64,
81            ReflectValueRef::F32(..) => RuntimeType::F32,
82            ReflectValueRef::F64(..) => RuntimeType::F64,
83            ReflectValueRef::Bool(..) => RuntimeType::Bool,
84            ReflectValueRef::String(..) => RuntimeType::String,
85            ReflectValueRef::Bytes(..) => RuntimeType::VecU8,
86            ReflectValueRef::Enum(d, ..) => RuntimeType::Enum(d.clone()),
87            ReflectValueRef::Message(m) => RuntimeType::Message(m.descriptor_dyn()),
88        }
89    }
90
91    /// Value is "non-zero"?
92    pub(crate) fn is_non_zero(&self) -> bool {
93        match self {
94            ReflectValueRef::U32(v) => *v != 0,
95            ReflectValueRef::U64(v) => *v != 0,
96            ReflectValueRef::I32(v) => *v != 0,
97            ReflectValueRef::I64(v) => *v != 0,
98            ReflectValueRef::F32(v) => *v != 0.,
99            ReflectValueRef::F64(v) => *v != 0.,
100            ReflectValueRef::Bool(v) => *v,
101            ReflectValueRef::String(v) => !v.is_empty(),
102            ReflectValueRef::Bytes(v) => !v.is_empty(),
103            ReflectValueRef::Enum(_d, v) => *v != 0,
104            ReflectValueRef::Message(_) => true,
105        }
106    }
107
108    pub(crate) fn is_initialized(&self) -> bool {
109        if let ReflectValueRef::Message(m) = self {
110            m.is_initialized_dyn()
111        } else {
112            true
113        }
114    }
115
116    /// Take `i32` value.
117    pub fn to_i32(&self) -> Option<i32> {
118        match *self {
119            ReflectValueRef::I32(v) => Some(v),
120            _ => None,
121        }
122    }
123
124    /// Take `i64` value.
125    pub fn to_i64(&self) -> Option<i64> {
126        match *self {
127            ReflectValueRef::I64(v) => Some(v),
128            _ => None,
129        }
130    }
131
132    /// Take `u32` value.
133    pub fn to_u32(&self) -> Option<u32> {
134        match *self {
135            ReflectValueRef::U32(v) => Some(v),
136            _ => None,
137        }
138    }
139
140    /// Take `u64` value.
141    pub fn to_u64(&self) -> Option<u64> {
142        match *self {
143            ReflectValueRef::U64(v) => Some(v),
144            _ => None,
145        }
146    }
147
148    /// Take `f32` value.
149    pub fn to_f32(&self) -> Option<f32> {
150        match *self {
151            ReflectValueRef::F32(v) => Some(v),
152            _ => None,
153        }
154    }
155
156    /// Take `f64` value.
157    pub fn to_f64(&self) -> Option<f64> {
158        match *self {
159            ReflectValueRef::F64(v) => Some(v),
160            _ => None,
161        }
162    }
163
164    /// Take `bool` value.
165    pub fn to_bool(&self) -> Option<bool> {
166        match *self {
167            ReflectValueRef::Bool(v) => Some(v),
168            _ => None,
169        }
170    }
171
172    /// Take `str` value.
173    pub fn to_str(&self) -> Option<&str> {
174        match *self {
175            ReflectValueRef::String(v) => Some(v),
176            _ => None,
177        }
178    }
179
180    /// Take `[u8]` value.
181    pub fn to_bytes(&self) -> Option<&[u8]> {
182        match *self {
183            ReflectValueRef::Bytes(v) => Some(v),
184            _ => None,
185        }
186    }
187
188    /// Take enum value.
189    pub fn to_enum_value(&self) -> Option<i32> {
190        match *self {
191            ReflectValueRef::Enum(_, v) => Some(v),
192            _ => None,
193        }
194    }
195
196    /// Take message value.
197    pub fn to_message(&self) -> Option<MessageRef<'a>> {
198        match self {
199            ReflectValueRef::Message(m) => Some(m.clone()),
200            _ => None,
201        }
202    }
203
204    /// Clone to a box
205    pub fn to_box(&self) -> ReflectValueBox {
206        match self {
207            ReflectValueRef::U32(v) => ReflectValueBox::U32(*v),
208            ReflectValueRef::U64(v) => ReflectValueBox::U64(*v),
209            ReflectValueRef::I32(v) => ReflectValueBox::I32(*v),
210            ReflectValueRef::I64(v) => ReflectValueBox::I64(*v),
211            ReflectValueRef::F32(v) => ReflectValueBox::F32(*v),
212            ReflectValueRef::F64(v) => ReflectValueBox::F64(*v),
213            ReflectValueRef::Bool(v) => ReflectValueBox::Bool(*v),
214            ReflectValueRef::String(v) => ReflectValueBox::String((*v).to_owned()),
215            ReflectValueRef::Bytes(v) => ReflectValueBox::Bytes((*v).to_owned()),
216            ReflectValueRef::Enum(d, v) => ReflectValueBox::Enum(d.clone(), *v),
217            ReflectValueRef::Message(v) => ReflectValueBox::Message(v.clone_box()),
218        }
219    }
220
221    /// Convert a value to arbitrary value.
222    pub fn downcast_clone<V: ProtobufValue>(&self) -> Result<V, Self> {
223        self.to_box().downcast().map_err(|_| self.clone())
224    }
225}
226
227pub enum ReflectValueMut<'a> {
228    Message(&'a mut dyn MessageDyn),
229}
230
231impl<'a> ReflectEq for ReflectValueRef<'a> {
232    fn reflect_eq(&self, that: &Self, mode: &ReflectEqMode) -> bool {
233        use crate::reflect::value::value_ref::ReflectValueRef::*;
234        match (self, that) {
235            (U32(a), U32(b)) => a == b,
236            (U64(a), U64(b)) => a == b,
237            (I32(a), I32(b)) => a == b,
238            (I64(a), I64(b)) => a == b,
239            (F32(a), F32(b)) => {
240                if a.is_nan() || b.is_nan() {
241                    a.is_nan() == b.is_nan() && mode.nan_equal
242                } else {
243                    a == b
244                }
245            }
246            (F64(a), F64(b)) => {
247                if a.is_nan() || b.is_nan() {
248                    a.is_nan() == b.is_nan() && mode.nan_equal
249                } else {
250                    a == b
251                }
252            }
253            (Bool(a), Bool(b)) => a == b,
254            (String(a), String(b)) => a == b,
255            (Bytes(a), Bytes(b)) => a == b,
256            (Enum(ad, a), Enum(bd, b)) => ad == bd && a == b,
257            (Message(a), Message(b)) => a.reflect_eq(b, mode),
258            _ => false,
259        }
260    }
261}
262
263impl<'a> PartialEq for ReflectValueRef<'a> {
264    fn eq(&self, other: &ReflectValueRef) -> bool {
265        use self::ReflectValueRef::*;
266        match (self, other) {
267            (U32(a), U32(b)) => a == b,
268            (U64(a), U64(b)) => a == b,
269            (I32(a), I32(b)) => a == b,
270            (I64(a), I64(b)) => a == b,
271            // should probably NaN == NaN here
272            (F32(a), F32(b)) => a == b,
273            (F64(a), F64(b)) => a == b,
274            (Bool(a), Bool(b)) => a == b,
275            (String(a), String(b)) => a == b,
276            (Bytes(a), Bytes(b)) => a == b,
277            (Enum(da, a), Enum(db, b)) => da == db && a == b,
278            (Message(a), Message(b)) => {
279                MessageDescriptor::reflect_eq_maybe_unrelated(&**a, &**b, &ReflectEqMode::default())
280            }
281            _ => false,
282        }
283    }
284}
285
286impl<'a> PartialEq<ReflectValueRef<'a>> for ReflectValueBox {
287    fn eq(&self, other: &ReflectValueRef) -> bool {
288        self.as_value_ref() == *other
289    }
290}
291
292// Panics if contained type is not hashable
293impl<'a> Hash for ReflectValueRef<'a> {
294    fn hash<H: Hasher>(&self, state: &mut H) {
295        use self::ReflectValueRef::*;
296        Hash::hash(&mem::discriminant(self), state);
297        match self {
298            U32(v) => Hash::hash(&v, state),
299            U64(v) => Hash::hash(&v, state),
300            I32(v) => Hash::hash(&v, state),
301            I64(v) => Hash::hash(&v, state),
302            Bool(v) => Hash::hash(&v, state),
303            String(v) => Hash::hash(&v, state),
304            Bytes(v) => Hash::hash(&v, state),
305            Enum(_d, v) => Hash::hash(v, state),
306            F32(_) | F64(_) | Message(_) => panic!("not hashable: {:?}", self),
307        }
308    }
309}
310
311impl<'a> From<EnumValueDescriptor> for ReflectValueRef<'a> {
312    fn from(v: EnumValueDescriptor) -> Self {
313        let number = v.value();
314        ReflectValueRef::Enum(v.enum_descriptor, number)
315    }
316}
317
318impl From<u32> for ReflectValueRef<'_> {
319    fn from(v: u32) -> Self {
320        ReflectValueRef::U32(v)
321    }
322}
323
324impl From<i32> for ReflectValueRef<'_> {
325    fn from(v: i32) -> Self {
326        ReflectValueRef::I32(v)
327    }
328}
329
330impl From<u64> for ReflectValueRef<'_> {
331    fn from(v: u64) -> Self {
332        ReflectValueRef::U64(v)
333    }
334}
335
336impl From<i64> for ReflectValueRef<'_> {
337    fn from(v: i64) -> Self {
338        ReflectValueRef::I64(v)
339    }
340}
341
342impl From<f32> for ReflectValueRef<'_> {
343    fn from(v: f32) -> Self {
344        ReflectValueRef::F32(v)
345    }
346}
347
348impl From<f64> for ReflectValueRef<'_> {
349    fn from(v: f64) -> Self {
350        ReflectValueRef::F64(v)
351    }
352}
353
354impl From<bool> for ReflectValueRef<'_> {
355    fn from(v: bool) -> Self {
356        ReflectValueRef::Bool(v)
357    }
358}
359
360impl<'a> From<&'a str> for ReflectValueRef<'a> {
361    fn from(v: &'a str) -> Self {
362        ReflectValueRef::String(v)
363    }
364}
365
366impl<'a> From<&'a [u8]> for ReflectValueRef<'a> {
367    fn from(v: &'a [u8]) -> Self {
368        ReflectValueRef::Bytes(v)
369    }
370}