protobuf/reflect/
value.rs

1use std::any::Any;
2
3#[cfg(feature = "bytes")]
4use bytes::Bytes;
5
6use super::*;
7#[cfg(feature = "bytes")]
8use crate::chars::Chars;
9
10/// Type implemented by all protobuf elementary types
11/// (ints, floats, bool, string, bytes, enums, messages).
12pub trait ProtobufValue: Any + 'static {
13    /// As ref
14    fn as_ref(&self) -> ReflectValueRef;
15
16    /// Convert to `Any`
17    fn as_any(&self) -> &dyn Any {
18        unimplemented!()
19    }
20
21    /// Is value non-zero?
22    fn is_non_zero(&self) -> bool {
23        self.as_ref().is_non_zero()
24    }
25
26    /// Return `ProtobufValueRef` if self is `Copy`.
27    ///
28    /// # Panics
29    ///
30    /// if `Self` is not `Copy`.
31    fn as_ref_copy(&self) -> ReflectValueRef<'static>
32//where Self : Copy // TODO
33    {
34        match self.as_ref() {
35            ReflectValueRef::Bool(v) => ReflectValueRef::Bool(v),
36            ReflectValueRef::U32(v) => ReflectValueRef::U32(v),
37            ReflectValueRef::U64(v) => ReflectValueRef::U64(v),
38            ReflectValueRef::I32(v) => ReflectValueRef::I32(v),
39            ReflectValueRef::I64(v) => ReflectValueRef::I64(v),
40            ReflectValueRef::F32(v) => ReflectValueRef::F32(v),
41            ReflectValueRef::F64(v) => ReflectValueRef::F64(v),
42            ReflectValueRef::Enum(v) => ReflectValueRef::Enum(v),
43            ReflectValueRef::String(..)
44            | ReflectValueRef::Bytes(..)
45            | ReflectValueRef::Message(..) => unreachable!(),
46        }
47    }
48}
49
50impl ProtobufValue for u32 {
51    fn as_ref(&self) -> ReflectValueRef {
52        ReflectValueRef::U32(*self)
53    }
54}
55
56impl ProtobufValue for u64 {
57    fn as_ref(&self) -> ReflectValueRef {
58        ReflectValueRef::U64(*self)
59    }
60}
61
62impl ProtobufValue for i32 {
63    fn as_ref(&self) -> ReflectValueRef {
64        ReflectValueRef::I32(*self)
65    }
66}
67
68impl ProtobufValue for i64 {
69    fn as_ref(&self) -> ReflectValueRef {
70        ReflectValueRef::I64(*self)
71    }
72}
73
74impl ProtobufValue for f32 {
75    fn as_ref(&self) -> ReflectValueRef {
76        ReflectValueRef::F32(*self)
77    }
78}
79
80impl ProtobufValue for f64 {
81    fn as_ref(&self) -> ReflectValueRef {
82        ReflectValueRef::F64(*self)
83    }
84}
85
86impl ProtobufValue for bool {
87    fn as_ref(&self) -> ReflectValueRef {
88        ReflectValueRef::Bool(*self)
89    }
90}
91
92impl ProtobufValue for String {
93    fn as_ref(&self) -> ReflectValueRef {
94        ReflectValueRef::String(*&self)
95    }
96}
97
98impl ProtobufValue for str {
99    fn as_ref(&self) -> ReflectValueRef {
100        ReflectValueRef::String(self)
101    }
102}
103
104impl ProtobufValue for Vec<u8> {
105    fn as_ref(&self) -> ReflectValueRef {
106        ReflectValueRef::Bytes(*&self)
107    }
108}
109
110#[cfg(feature = "bytes")]
111impl ProtobufValue for Bytes {
112    fn as_ref(&self) -> ReflectValueRef {
113        ReflectValueRef::Bytes(&*self)
114    }
115}
116
117#[cfg(feature = "bytes")]
118impl ProtobufValue for Chars {
119    fn as_ref(&self) -> ReflectValueRef {
120        ReflectValueRef::String(&*self)
121    }
122}
123
124// conflicting implementations, so generated code is used instead
125/*
126impl<E : ProtobufEnum> ProtobufValue for E {
127    fn as_ref(&self) -> ProtobufValueRef {
128        ProtobufValueRef::Enum(self.descriptor())
129    }
130}
131
132impl<M : Message> ProtobufValue for M {
133    fn as_ref(&self) -> ProtobufValueRef {
134        ProtobufValueRef::Message(self)
135    }
136}
137*/
138
139/// A reference to a value
140#[derive(Debug)]
141pub enum ReflectValueRef<'a> {
142    /// `u32`
143    U32(u32),
144    /// `u64`
145    U64(u64),
146    /// `i32`
147    I32(i32),
148    /// `i64`
149    I64(i64),
150    /// `f32`
151    F32(f32),
152    /// `f64`
153    F64(f64),
154    /// `bool`
155    Bool(bool),
156    /// `string`
157    String(&'a str),
158    /// `bytes`
159    Bytes(&'a [u8]),
160    /// `enum`
161    // TODO: change to (i32, EnumDescriptor)
162    Enum(&'static EnumValueDescriptor),
163    /// `message`
164    Message(&'a dyn Message),
165}
166
167impl<'a> ReflectValueRef<'a> {
168    /// Value is "non-zero"?
169    #[doc(hidden)]
170    pub fn is_non_zero(&self) -> bool {
171        match *self {
172            ReflectValueRef::U32(v) => v != 0,
173            ReflectValueRef::U64(v) => v != 0,
174            ReflectValueRef::I32(v) => v != 0,
175            ReflectValueRef::I64(v) => v != 0,
176            ReflectValueRef::F32(v) => v != 0.,
177            ReflectValueRef::F64(v) => v != 0.,
178            ReflectValueRef::Bool(v) => v,
179            ReflectValueRef::String(v) => !v.is_empty(),
180            ReflectValueRef::Bytes(v) => !v.is_empty(),
181            ReflectValueRef::Enum(v) => v.value() != 0,
182            ReflectValueRef::Message(_) => true,
183        }
184    }
185}