protobuf/reflect/
runtime_type_box.rs
1use std::fmt;
2
3use protobuf_support::lexer::float::parse_protobuf_float;
4use protobuf_support::lexer::str_lit::StrLit;
5
6use crate::descriptor::field_descriptor_proto;
7use crate::reflect::EnumDescriptor;
8use crate::reflect::MessageDescriptor;
9use crate::reflect::MessageRef;
10use crate::reflect::ReflectValueBox;
11use crate::reflect::ReflectValueRef;
12
13#[derive(Debug, Clone, Eq, PartialEq)]
15pub enum RuntimeType {
16 I32,
18 I64,
20 U32,
22 U64,
24 F32,
26 F64,
28 Bool,
30 String,
32 VecU8,
34 Enum(EnumDescriptor),
36 Message(MessageDescriptor),
38}
39
40impl RuntimeType {
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
57 pub(crate) fn default_value_box(&self) -> ReflectValueBox {
58 self.default_value_ref().to_box()
59 }
60
61 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
92 pub(crate) fn parse_proto_default_value(&self, value: &str) -> Result<ReflectValueBox, ()> {
93 match self {
94 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 RuntimeType::String => Ok(ReflectValueBox::String(value.to_owned())),
116 RuntimeType::VecU8 => StrLit {
118 escaped: value.to_owned(),
119 }
120 .decode_bytes()
121 .map_err(|_| ())
122 .map(ReflectValueBox::Bytes),
123 RuntimeType::Enum(_) => {
124 Err(())
126 }
127 RuntimeType::Message(_) => {
128 Err(())
130 }
131 }
132 }
133}
134
135impl fmt::Display for RuntimeType {
136 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}