1 use std::fmt; 2 3 use protobuf_support::lexer::float::parse_protobuf_float; 4 use protobuf_support::lexer::str_lit::StrLit; 5 6 use crate::descriptor::field_descriptor_proto; 7 use crate::reflect::EnumDescriptor; 8 use crate::reflect::MessageDescriptor; 9 use crate::reflect::MessageRef; 10 use crate::reflect::ReflectValueBox; 11 use crate::reflect::ReflectValueRef; 12 13 /// Runtime representation of elementary protobuf type. 14 #[derive(Debug, Clone, Eq, PartialEq)] 15 pub enum RuntimeType { 16 /// `i32` 17 I32, 18 /// `i64` 19 I64, 20 /// `u32` 21 U32, 22 /// `u64` 23 U64, 24 /// `f32` 25 F32, 26 /// `f64` 27 F64, 28 /// `bool` 29 Bool, 30 /// [`String`](std::string::String) 31 String, 32 /// [`Vec<u8>`](std::vec::Vec) 33 VecU8, 34 /// `enum` 35 Enum(EnumDescriptor), 36 /// `message` 37 Message(MessageDescriptor), 38 } 39 40 impl RuntimeType { default_value_ref(&self) -> ReflectValueRef<'static>41 pub(crate) fn default_value_ref(&self) -> ReflectValueRef<'static> { 42 match self { 43 RuntimeType::I32 => ReflectValueRef::I32(0), 44 RuntimeType::I64 => ReflectValueRef::I64(0), 45 RuntimeType::U32 => ReflectValueRef::U32(0), 46 RuntimeType::U64 => ReflectValueRef::U64(0), 47 RuntimeType::F32 => ReflectValueRef::F32(0.0), 48 RuntimeType::F64 => ReflectValueRef::F64(0.0), 49 RuntimeType::Bool => ReflectValueRef::Bool(false), 50 RuntimeType::String => ReflectValueRef::String(""), 51 RuntimeType::VecU8 => ReflectValueRef::Bytes(b""), 52 RuntimeType::Enum(e) => ReflectValueRef::Enum(e.clone(), e.default_value().value()), 53 RuntimeType::Message(m) => ReflectValueRef::Message(MessageRef::default_instance(m)), 54 } 55 } 56 default_value_box(&self) -> ReflectValueBox57 pub(crate) fn default_value_box(&self) -> ReflectValueBox { 58 self.default_value_ref().to_box() 59 } 60 61 /// Rust type from protobuf type. 62 /// 63 /// # Panics 64 /// 65 /// Panics for message or enum types (because they can't be resolved without context). from_proto_type(t: field_descriptor_proto::Type) -> RuntimeType66 pub(crate) fn from_proto_type(t: field_descriptor_proto::Type) -> RuntimeType { 67 match t { 68 field_descriptor_proto::Type::TYPE_UINT32 => RuntimeType::U32, 69 field_descriptor_proto::Type::TYPE_UINT64 => RuntimeType::U64, 70 field_descriptor_proto::Type::TYPE_INT32 => RuntimeType::I32, 71 field_descriptor_proto::Type::TYPE_INT64 => RuntimeType::I64, 72 field_descriptor_proto::Type::TYPE_SINT32 => RuntimeType::I32, 73 field_descriptor_proto::Type::TYPE_SINT64 => RuntimeType::I64, 74 field_descriptor_proto::Type::TYPE_FIXED32 => RuntimeType::U32, 75 field_descriptor_proto::Type::TYPE_FIXED64 => RuntimeType::U64, 76 field_descriptor_proto::Type::TYPE_SFIXED64 => RuntimeType::I64, 77 field_descriptor_proto::Type::TYPE_SFIXED32 => RuntimeType::I32, 78 field_descriptor_proto::Type::TYPE_BOOL => RuntimeType::Bool, 79 field_descriptor_proto::Type::TYPE_STRING => RuntimeType::String, 80 field_descriptor_proto::Type::TYPE_BYTES => RuntimeType::VecU8, 81 field_descriptor_proto::Type::TYPE_FLOAT => RuntimeType::F32, 82 field_descriptor_proto::Type::TYPE_DOUBLE => RuntimeType::F64, 83 field_descriptor_proto::Type::TYPE_ENUM 84 | field_descriptor_proto::Type::TYPE_MESSAGE 85 | field_descriptor_proto::Type::TYPE_GROUP => panic!( 86 "{:?} cannot be converted to runtime type without context", 87 t 88 ), 89 } 90 } 91 parse_proto_default_value(&self, value: &str) -> Result<ReflectValueBox, ()>92 pub(crate) fn parse_proto_default_value(&self, value: &str) -> Result<ReflectValueBox, ()> { 93 match self { 94 // For booleans, "true" or "false" 95 RuntimeType::Bool => { 96 if value == "true" { 97 Ok(ReflectValueBox::Bool(true)) 98 } else if value == "false" { 99 Ok(ReflectValueBox::Bool(false)) 100 } else { 101 Err(()) 102 } 103 } 104 RuntimeType::I32 => value.parse().map_err(|_| ()).map(ReflectValueBox::I32), 105 RuntimeType::I64 => value.parse().map_err(|_| ()).map(ReflectValueBox::I64), 106 RuntimeType::U32 => value.parse().map_err(|_| ()).map(ReflectValueBox::U32), 107 RuntimeType::U64 => value.parse().map_err(|_| ()).map(ReflectValueBox::U64), 108 RuntimeType::F32 => parse_protobuf_float(value) 109 .map_err(|_| ()) 110 .map(|v| ReflectValueBox::F32(v as f32)), 111 RuntimeType::F64 => parse_protobuf_float(value) 112 .map_err(|_| ()) 113 .map(ReflectValueBox::F64), 114 // For strings, contains the default text contents (not escaped in any way) 115 RuntimeType::String => Ok(ReflectValueBox::String(value.to_owned())), 116 // For bytes, contains the C escaped value. All bytes >= 128 are escaped 117 RuntimeType::VecU8 => StrLit { 118 escaped: value.to_owned(), 119 } 120 .decode_bytes() 121 .map_err(|_| ()) 122 .map(ReflectValueBox::Bytes), 123 RuntimeType::Enum(_) => { 124 // Handled outside. 125 Err(()) 126 } 127 RuntimeType::Message(_) => { 128 // Message cannot have default value. 129 Err(()) 130 } 131 } 132 } 133 } 134 135 impl fmt::Display for RuntimeType { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 137 match self { 138 RuntimeType::I32 => write!(f, "i32"), 139 RuntimeType::I64 => write!(f, "i64"), 140 RuntimeType::U32 => write!(f, "u32"), 141 RuntimeType::U64 => write!(f, "u64"), 142 RuntimeType::F32 => write!(f, "f32"), 143 RuntimeType::F64 => write!(f, "f64"), 144 RuntimeType::Bool => write!(f, "bool"), 145 RuntimeType::String => write!(f, "String"), 146 RuntimeType::VecU8 => write!(f, "Vec<u8>"), 147 RuntimeType::Enum(e) => write!(f, "{}", e.full_name()), 148 RuntimeType::Message(m) => write!(f, "{}", m.full_name()), 149 } 150 } 151 } 152