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