• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::any::Any;
2 
3 #[cfg(feature = "bytes")]
4 use crate::chars::Chars;
5 #[cfg(feature = "bytes")]
6 use bytes::Bytes;
7 
8 use super::*;
9 
10 /// Type implemented by all protobuf elementary types
11 /// (ints, floats, bool, string, bytes, enums, messages).
12 pub trait ProtobufValue: Any + 'static {
13     /// As ref
as_ref(&self) -> ReflectValueRef14     fn as_ref(&self) -> ReflectValueRef;
15 
16     /// Convert to `Any`
as_any(&self) -> &dyn Any17     fn as_any(&self) -> &dyn Any {
18         unimplemented!()
19     }
20 
21     /// Is value non-zero?
is_non_zero(&self) -> bool22     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`.
as_ref_copy(&self) -> ReflectValueRef<'static>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 
50 impl ProtobufValue for u32 {
as_ref(&self) -> ReflectValueRef51     fn as_ref(&self) -> ReflectValueRef {
52         ReflectValueRef::U32(*self)
53     }
54 }
55 
56 impl ProtobufValue for u64 {
as_ref(&self) -> ReflectValueRef57     fn as_ref(&self) -> ReflectValueRef {
58         ReflectValueRef::U64(*self)
59     }
60 }
61 
62 impl ProtobufValue for i32 {
as_ref(&self) -> ReflectValueRef63     fn as_ref(&self) -> ReflectValueRef {
64         ReflectValueRef::I32(*self)
65     }
66 }
67 
68 impl ProtobufValue for i64 {
as_ref(&self) -> ReflectValueRef69     fn as_ref(&self) -> ReflectValueRef {
70         ReflectValueRef::I64(*self)
71     }
72 }
73 
74 impl ProtobufValue for f32 {
as_ref(&self) -> ReflectValueRef75     fn as_ref(&self) -> ReflectValueRef {
76         ReflectValueRef::F32(*self)
77     }
78 }
79 
80 impl ProtobufValue for f64 {
as_ref(&self) -> ReflectValueRef81     fn as_ref(&self) -> ReflectValueRef {
82         ReflectValueRef::F64(*self)
83     }
84 }
85 
86 impl ProtobufValue for bool {
as_ref(&self) -> ReflectValueRef87     fn as_ref(&self) -> ReflectValueRef {
88         ReflectValueRef::Bool(*self)
89     }
90 }
91 
92 impl ProtobufValue for String {
as_ref(&self) -> ReflectValueRef93     fn as_ref(&self) -> ReflectValueRef {
94         ReflectValueRef::String(*&self)
95     }
96 }
97 
98 impl ProtobufValue for str {
as_ref(&self) -> ReflectValueRef99     fn as_ref(&self) -> ReflectValueRef {
100         ReflectValueRef::String(self)
101     }
102 }
103 
104 impl ProtobufValue for Vec<u8> {
as_ref(&self) -> ReflectValueRef105     fn as_ref(&self) -> ReflectValueRef {
106         ReflectValueRef::Bytes(*&self)
107     }
108 }
109 
110 #[cfg(feature = "bytes")]
111 impl ProtobufValue for Bytes {
as_ref(&self) -> ReflectValueRef112     fn as_ref(&self) -> ReflectValueRef {
113         ReflectValueRef::Bytes(&*self)
114     }
115 }
116 
117 #[cfg(feature = "bytes")]
118 impl ProtobufValue for Chars {
as_ref(&self) -> ReflectValueRef119     fn as_ref(&self) -> ReflectValueRef {
120         ReflectValueRef::String(&*self)
121     }
122 }
123 
124 // conflicting implementations, so generated code is used instead
125 /*
126 impl<E : ProtobufEnum> ProtobufValue for E {
127     fn as_ref(&self) -> ProtobufValueRef {
128         ProtobufValueRef::Enum(self.descriptor())
129     }
130 }
131 
132 impl<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)]
141 pub 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 
167 impl<'a> ReflectValueRef<'a> {
168     /// Value is "non-zero"?
169     #[doc(hidden)]
is_non_zero(&self) -> bool170     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 }
186