1 use crate::descriptor::FieldDescriptorProto; 2 use crate::descriptor::FieldDescriptorProto_Label; 3 use crate::json::json_name; 4 use crate::message::Message; 5 use crate::reflect::acc::Accessor; 6 use crate::reflect::acc::FieldAccessor; 7 use crate::reflect::map::ReflectMap; 8 use crate::reflect::repeated::ReflectRepeated; 9 use crate::reflect::EnumValueDescriptor; 10 use crate::reflect::ReflectValueRef; 11 12 /// Reference to a value stored in a field, optional, repeated or map. 13 // TODO: implement Eq 14 pub enum ReflectFieldRef<'a> { 15 /// Singular field, optional or required in proto3 and just plain field in proto3 16 Optional(Option<ReflectValueRef<'a>>), 17 /// Repeated field 18 Repeated(&'a dyn ReflectRepeated), 19 /// Map field 20 Map(&'a dyn ReflectMap), 21 } 22 23 /// Field descriptor. 24 /// 25 /// Can be used for runtime reflection. 26 pub struct FieldDescriptor { 27 proto: &'static FieldDescriptorProto, 28 accessor: FieldAccessor, 29 json_name: String, 30 } 31 32 impl FieldDescriptor { new( accessor: FieldAccessor, proto: &'static FieldDescriptorProto, ) -> FieldDescriptor33 pub(crate) fn new( 34 accessor: FieldAccessor, 35 proto: &'static FieldDescriptorProto, 36 ) -> FieldDescriptor { 37 assert_eq!(proto.get_name(), accessor.name); 38 let json_name = if !proto.get_json_name().is_empty() { 39 proto.get_json_name().to_string() 40 } else { 41 json_name(proto.get_name()) 42 }; 43 FieldDescriptor { 44 proto, 45 accessor, 46 // probably could be lazy-init 47 json_name, 48 } 49 } 50 51 /// Get `.proto` description of field proto(&self) -> &'static FieldDescriptorProto52 pub fn proto(&self) -> &'static FieldDescriptorProto { 53 self.proto 54 } 55 56 /// Field name as specified in `.proto` file name(&self) -> &'static str57 pub fn name(&self) -> &'static str { 58 self.proto.get_name() 59 } 60 61 /// JSON field name. 62 /// 63 /// Can be different from `.proto` field name. 64 /// 65 /// See [JSON mapping][json] for details. 66 /// 67 /// [json]: https://developers.google.com/protocol-buffers/docs/proto3#json json_name(&self) -> &str68 pub fn json_name(&self) -> &str { 69 &self.json_name 70 } 71 72 /// If this field repeated? is_repeated(&self) -> bool73 pub fn is_repeated(&self) -> bool { 74 self.proto.get_label() == FieldDescriptorProto_Label::LABEL_REPEATED 75 } 76 77 /// Check if field is set in given message. 78 /// 79 /// For repeated field or map field return `true` if 80 /// collection is not empty. 81 /// 82 /// # Panics 83 /// 84 /// If this field belongs to a different message type. has_field(&self, m: &dyn Message) -> bool85 pub fn has_field(&self, m: &dyn Message) -> bool { 86 match &self.accessor.accessor { 87 Accessor::V1(a) => a.has_field_generic(m), 88 } 89 } 90 91 /// Return length of repeated field. 92 /// 93 /// For singular field return `1` if field is set and `0` otherwise. 94 /// 95 /// # Panics 96 /// 97 /// If this field belongs to a different message type. len_field(&self, m: &dyn Message) -> usize98 pub fn len_field(&self, m: &dyn Message) -> usize { 99 match &self.accessor.accessor { 100 Accessor::V1(a) => a.len_field_generic(m), 101 } 102 } 103 104 /// Get message field or default instance if field is unset. 105 /// 106 /// # Panics 107 /// If this field belongs to a different message type or 108 /// field type is not message. get_message<'a>(&self, m: &'a dyn Message) -> &'a dyn Message109 pub fn get_message<'a>(&self, m: &'a dyn Message) -> &'a dyn Message { 110 match &self.accessor.accessor { 111 Accessor::V1(a) => a.get_message_generic(m), 112 } 113 } 114 115 /// Get `enum` field. 116 /// 117 /// # Panics 118 /// 119 /// If this field belongs to a different message type 120 /// or field type is not singular `enum`. get_enum(&self, m: &dyn Message) -> &'static EnumValueDescriptor121 pub fn get_enum(&self, m: &dyn Message) -> &'static EnumValueDescriptor { 122 match &self.accessor.accessor { 123 Accessor::V1(a) => a.get_enum_generic(m), 124 } 125 } 126 127 /// Get `string` field. 128 /// 129 /// # Panics 130 /// 131 /// If this field belongs to a different message type 132 /// or field type is not singular `string`. get_str<'a>(&self, m: &'a dyn Message) -> &'a str133 pub fn get_str<'a>(&self, m: &'a dyn Message) -> &'a str { 134 match &self.accessor.accessor { 135 Accessor::V1(a) => a.get_str_generic(m), 136 } 137 } 138 139 /// Get `bytes` field. 140 /// 141 /// # Panics 142 /// 143 /// If this field belongs to a different message type 144 /// or field type is not singular `bytes`. get_bytes<'a>(&self, m: &'a dyn Message) -> &'a [u8]145 pub fn get_bytes<'a>(&self, m: &'a dyn Message) -> &'a [u8] { 146 match &self.accessor.accessor { 147 Accessor::V1(a) => a.get_bytes_generic(m), 148 } 149 } 150 151 /// Get `u32` field. 152 /// 153 /// # Panics 154 /// 155 /// If this field belongs to a different message type 156 /// or field type is not singular `u32`. get_u32(&self, m: &dyn Message) -> u32157 pub fn get_u32(&self, m: &dyn Message) -> u32 { 158 match &self.accessor.accessor { 159 Accessor::V1(a) => a.get_u32_generic(m), 160 } 161 } 162 163 /// Get `u64` field. 164 /// 165 /// # Panics 166 /// 167 /// If this field belongs to a different message type 168 /// or field type is not singular `u64`. get_u64(&self, m: &dyn Message) -> u64169 pub fn get_u64(&self, m: &dyn Message) -> u64 { 170 match &self.accessor.accessor { 171 Accessor::V1(a) => a.get_u64_generic(m), 172 } 173 } 174 175 /// Get `i32` field. 176 /// 177 /// # Panics 178 /// 179 /// If this field belongs to a different message type 180 /// or field type is not singular `i32`. get_i32(&self, m: &dyn Message) -> i32181 pub fn get_i32(&self, m: &dyn Message) -> i32 { 182 match &self.accessor.accessor { 183 Accessor::V1(a) => a.get_i32_generic(m), 184 } 185 } 186 187 /// Get `i64` field. 188 /// 189 /// # Panics 190 /// 191 /// If this field belongs to a different message type 192 /// or field type is not singular `i64`. get_i64(&self, m: &dyn Message) -> i64193 pub fn get_i64(&self, m: &dyn Message) -> i64 { 194 match &self.accessor.accessor { 195 Accessor::V1(a) => a.get_i64_generic(m), 196 } 197 } 198 199 /// Get `bool` field. 200 /// 201 /// # Panics 202 /// 203 /// If this field belongs to a different message type or 204 /// field type is not singular `bool`. get_bool(&self, m: &dyn Message) -> bool205 pub fn get_bool(&self, m: &dyn Message) -> bool { 206 match &self.accessor.accessor { 207 Accessor::V1(a) => a.get_bool_generic(m), 208 } 209 } 210 211 /// Get `float` field. 212 /// 213 /// # Panics 214 /// 215 /// If this field belongs to a different message type or 216 /// field type is not singular `float`. get_f32(&self, m: &dyn Message) -> f32217 pub fn get_f32(&self, m: &dyn Message) -> f32 { 218 match &self.accessor.accessor { 219 Accessor::V1(a) => a.get_f32_generic(m), 220 } 221 } 222 223 /// Get `double` field. 224 /// 225 /// # Panics 226 /// 227 /// If this field belongs to a different message type 228 /// or field type is not singular `double`. get_f64(&self, m: &dyn Message) -> f64229 pub fn get_f64(&self, m: &dyn Message) -> f64 { 230 match &self.accessor.accessor { 231 Accessor::V1(a) => a.get_f64_generic(m), 232 } 233 } 234 235 /// Get field of any type. 236 /// 237 /// # Panics 238 /// 239 /// If this field belongs to a different message type. get_reflect<'a>(&self, m: &'a dyn Message) -> ReflectFieldRef<'a>240 pub fn get_reflect<'a>(&self, m: &'a dyn Message) -> ReflectFieldRef<'a> { 241 match &self.accessor.accessor { 242 Accessor::V1(a) => a.get_reflect(m), 243 } 244 } 245 } 246