protobuf_json_temp/
lib.rs1extern crate protobuf;
2extern crate serde_json;
3
4use protobuf::Message;
5use protobuf::descriptor::FieldDescriptorProto_Type;
6use protobuf::reflect::FieldDescriptor;
7
8#[cfg(test)]
9mod tests;
10
11pub fn proto_to_json(message: &dyn Message) -> serde_json::Value {
12 let mut map = serde_json::Map::new();
13
14 for field in message.descriptor().fields() {
15 match field_to_json(message, field) {
16 Some(x) => {
17 map.insert(field.name().to_string(), x)
18 },
19 None => continue
20 };
21 }
22 serde_json::Value::Object(map)
23}
24
25fn field_to_json(m: &dyn Message, fd: &FieldDescriptor) -> Option<serde_json::Value> {
26 if fd.is_repeated() {
27 match fd.len_field(m) {
28 0 => None,
29 _ => Some(repeated_field_to_json(m, fd)),
30 }
31 } else if fd.has_field(m) {
32 Some(singular_field_to_json(m, fd))
33 } else {
34 None
35 }
36}
37
38#[allow(dead_code)]
43fn extract_vec_shim<'a, T>(
44 message: &'a dyn Message,
45 get_size_fn: &dyn Fn(&dyn Message) -> usize,
46 extract_one_fn: &dyn Fn(&'a dyn Message, usize) -> &'a T) -> Vec<&'a T> {
47
48 let size = get_size_fn(message);
49 let mut v = Vec::new();
50 for i in 0..size {
51 v.push(extract_one_fn(message, i));
52 }
53 v
54}
55
56fn repeated_entry_as_value(pbval: &dyn protobuf::reflect::ProtobufValue) -> serde_json::Value {
57 use protobuf::reflect::ProtobufValueRef;
58 use serde_json::Value;
59 use serde_json::Number;
60
61 match pbval.as_ref() {
63 ProtobufValueRef::Bool(x) => Value::Bool(x),
64 ProtobufValueRef::U32(x) => Value::Number(Number::from(x)),
65 ProtobufValueRef::U64(x) => Value::Number(Number::from(x)),
66 ProtobufValueRef::I32(x) => Value::Number(Number::from(x)),
67 ProtobufValueRef::I64(x) => Value::Number(Number::from(x)),
68 ProtobufValueRef::F32(x) => Value::Number(Number::from_f64(x as f64).expect("repeated f32")),
69 ProtobufValueRef::F64(x) => Value::Number(Number::from_f64(x).expect("repeated f64")),
70 ProtobufValueRef::Enum(x) => serde_json::Value::String(x.name().to_string()),
71 ProtobufValueRef::String(x) => serde_json::Value::String(x.to_string()),
72 ProtobufValueRef::Bytes(x) => serde_json::Value::String(std::str::from_utf8(x).expect("repeated bytes to string").to_string()),
73 ProtobufValueRef::Message(x) => proto_to_json(x),
74 }
75}
76
77fn repeated_field_to_json(message: &dyn Message,
78 field_descriptor: &FieldDescriptor) -> serde_json::Value {
79
80
81 match field_descriptor.get_reflect(message) {
82 protobuf::reflect::ReflectFieldRef::Repeated(rep_field) => {
84 return serde_json::Value::Array(
85 rep_field.into_iter().map(repeated_entry_as_value).collect());
86 },
87 _ => panic!("No repeated field"),
88 }
89
90}
91
92fn singular_field_to_json(message: &dyn protobuf::Message,
93 field_descriptor: &protobuf::reflect::FieldDescriptor) -> serde_json::Value {
94 match field_descriptor.proto().get_field_type() {
95 FieldDescriptorProto_Type::TYPE_DOUBLE => {
96 serde_json::Value::from(field_descriptor.get_f64(message))
97 },
98 FieldDescriptorProto_Type::TYPE_FLOAT => {
99 serde_json::Value::from(f64::from(field_descriptor.get_f32(message)))
100 },
101 FieldDescriptorProto_Type::TYPE_INT32 |
102 FieldDescriptorProto_Type::TYPE_SINT32 |
103 FieldDescriptorProto_Type::TYPE_SFIXED32 => {
104 serde_json::Value::from(i64::from(field_descriptor.get_i32(message)))
105 },
106 FieldDescriptorProto_Type::TYPE_INT64 |
107 FieldDescriptorProto_Type::TYPE_SINT64 |
108 FieldDescriptorProto_Type::TYPE_SFIXED64 => {
109 serde_json::Value::from(field_descriptor.get_i64(message))
110 },
111 FieldDescriptorProto_Type::TYPE_UINT32 |
112 FieldDescriptorProto_Type::TYPE_FIXED32 => {
113 serde_json::Value::from(u64::from(field_descriptor.get_u32(message)))
114 },
115 FieldDescriptorProto_Type::TYPE_UINT64 |
116 FieldDescriptorProto_Type::TYPE_FIXED64 => {
117 serde_json::Value::from(field_descriptor.get_u64(message))
118 },
119 FieldDescriptorProto_Type::TYPE_BOOL => {
120 serde_json::Value::Bool(field_descriptor.get_bool(message))
121 },
122 FieldDescriptorProto_Type::TYPE_STRING => {
123 serde_json::Value::String(field_descriptor.get_str(message).to_string())
124 },
125 FieldDescriptorProto_Type::TYPE_BYTES => {
126 serde_json::Value::String(
127 std::str::from_utf8(
128 field_descriptor.get_bytes(message)).unwrap().to_string())
129 },
130 FieldDescriptorProto_Type::TYPE_MESSAGE => {
131 let sub_message: &dyn protobuf::Message =
132 field_descriptor.get_message(message);
133 proto_to_json(sub_message)
134 },
135 FieldDescriptorProto_Type::TYPE_ENUM => {
136 serde_json::Value::String(
137 field_descriptor.get_enum(message).name().to_string())
138
139 },
140 FieldDescriptorProto_Type::TYPE_GROUP => unimplemented!(),
141 }
142}