use crate::{serial::api_descriptor::{is_array, ServiceApiDescriptor}, base::status::Status};
use protobuf::descriptor::field_descriptor_proto::Type;
use protobuf::descriptor::FieldDescriptorProto;
use protobuf::CodedInputStream;
use serde_json::Value;
use super::api_descriptor::{is_map, DescriptorProtoHolder};
fn put_value_in_json(
field: &FieldDescriptorProto,
value: &Value,
value_map: &mut serde_json::map::Map<String, Value>,
) {
let is_array = is_array(field);
if is_array {
let arr_value = value_map.get_mut(field.name.as_ref().unwrap());
if arr_value.is_none() {
let mut arr_value: Vec<Value> = vec![];
arr_value.push(value.clone());
value_map.insert(
field.name.clone().unwrap(),
serde_json::Value::Array(arr_value),
);
} else {
let inner_value = arr_value.unwrap();
let arr_value = inner_value.as_array_mut().unwrap();
arr_value.push(value.clone());
}
} else {
value_map.insert(field.name.clone().unwrap(), value.clone());
}
}
fn read_proto_to_json_value(
field_type: Type,
field: &FieldDescriptorProto,
msg_name: &str,
service_api_descriptor: &ServiceApiDescriptor,
input_stream: &mut CodedInputStream,
) -> Result<Value, Status> {
match field_type {
Type::TYPE_INT64 => {
let value = input_stream.read_int64();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 i64 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_UINT64 => {
let value = input_stream.read_uint64();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 ui64 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_INT32 => {
let value = input_stream.read_int32();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 i32 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_FIXED64 => {
let value = input_stream.read_fixed64();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 fixed64 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_FIXED32 => {
let value = input_stream.read_fixed32();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 fixed32 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_UINT32 => {
let value = input_stream.read_uint32();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 u32 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_ENUM => {
let value = input_stream.read_int32();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 enum 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_SFIXED32 => {
let value = input_stream.read_sfixed32();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 sfixed32 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_SFIXED64 => {
let value = input_stream.read_sfixed64();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 sfixed64 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_SINT32 => {
let value = input_stream.read_sint32();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 sint32 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_SINT64 => {
let value = input_stream.read_sint64();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 sint64 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from(value));
Ok(value)
}
Type::TYPE_DOUBLE => {
let value = input_stream.read_double();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 double 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Number(serde_json::Number::from_f64(value).unwrap());
Ok(value)
}
Type::TYPE_FLOAT => {
let value = input_stream.read_float();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 float 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value =
serde_json::Value::Number(serde_json::Number::from_f64(value as f64).unwrap());
Ok(value)
}
Type::TYPE_STRING => {
let value = input_stream.read_string();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 string 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::String(value);
Ok(value)
}
Type::TYPE_MESSAGE => {
let type_name = field.type_name.as_ref().unwrap();
let len = input_stream.read_raw_varint64();
if len.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 message 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let len = len.unwrap();
let old_limit = input_stream.push_limit(len);
if old_limit.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 message 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let old_limit = old_limit.unwrap();
let value = proto_to_json_by_is(type_name, service_api_descriptor, input_stream)?;
input_stream.pop_limit(old_limit);
Ok(value)
}
Type::TYPE_BOOL => {
let value = input_stream.read_bool();
if value.is_err() {
return Err(Status::error(format!(
"读取 {} {} 为 bool 错误!",
msg_name,
field.name.as_ref().unwrap()
)));
}
let value = value.unwrap();
let value = serde_json::Value::Bool(value);
Ok(value)
}
_ => {
return Err(Status::error(format!(
"无法识别 {} {} 的类型",
msg_name,
field.name.as_ref().unwrap()
)));
}
}
}
fn get_field(tag: u32, desc_proto_holder: &DescriptorProtoHolder) -> Option<&FieldDescriptorProto> {
let field_index = desc_proto_holder.field_index_map.get(&tag);
if field_index.is_none() {
return None;
}
let field_index = field_index.unwrap();
desc_proto_holder
.descriptor_proto
.field
.get(*field_index as usize)
}
pub fn proto_to_json_by_is(
msg_name: &str,
service_api_descriptor: &ServiceApiDescriptor,
input_stream: &mut CodedInputStream,
) -> Result<Value, Status> {
let msg_descriptor_holder = service_api_descriptor.message_descriptor_holder.get(msg_name);
if msg_descriptor_holder.is_none() {
return Err(Status::error(format!("类型 {} 不存在", msg_name)));
}
let msg_descriptor_holder = msg_descriptor_holder.unwrap();
let mut value_map = serde_json::map::Map::new();
while let Some(tag) = input_stream.read_raw_tag_or_eof().unwrap() {
let field = get_field(tag, msg_descriptor_holder);
if field.is_none() {
continue;
}
let field = field.unwrap();
let field_type = field.type_.unwrap().unwrap();
if field_type == Type::TYPE_MESSAGE && is_map(field, service_api_descriptor) {
let len = input_stream.read_raw_varint32().unwrap();
let old_limit = input_stream.push_limit(len as u64).unwrap();
let map_type_name = field.type_name.as_ref().unwrap();
let map_msg_descriptor_holder = service_api_descriptor
.message_descriptor_holder
.get(map_type_name);
if map_msg_descriptor_holder.is_none() {
return Err(Status::error(format!(
"map {} 描述不存在",
map_type_name
)));
}
let map_msg_descriptor_holder = map_msg_descriptor_holder.unwrap();
let mut key: Value = Value::Null;
let mut value: Value = Value::Null;
while let Some(tag) = input_stream.read_raw_tag_or_eof().unwrap() {
let field = get_field(tag, map_msg_descriptor_holder);
if field.is_none() {
continue;
}
let field = field.unwrap();
let field_type = field.type_.unwrap().unwrap();
if field.number() == 1 {
key = read_proto_to_json_value(
field_type,
field,
msg_name,
service_api_descriptor,
input_stream,
)?;
} else {
value = read_proto_to_json_value(
field_type,
field,
msg_name,
service_api_descriptor,
input_stream,
)?;
}
}
input_stream.pop_limit(old_limit);
let obj_value = value_map.get_mut(field.name.as_ref().unwrap());
if obj_value.is_none() {
let mut obj_value = serde_json::map::Map::new();
obj_value.insert(key.as_str().unwrap().to_string(), value);
value_map.insert(field.name.clone().unwrap(), Value::Object(obj_value));
} else {
let obj_value = obj_value.unwrap();
let obj_value = obj_value.as_object_mut().unwrap();
obj_value.insert(key.as_str().unwrap().to_string(), value);
}
} else {
let value = read_proto_to_json_value(
field_type,
field,
msg_name,
service_api_descriptor,
input_stream,
)?;
put_value_in_json(field, &value, &mut value_map);
}
}
let value = Value::Object(value_map);
Ok(value)
}
pub fn proto_to_json(
proto_bytes: &Vec<u8>,
msg_name: &str,
service_api_descriptor: &ServiceApiDescriptor,
) -> Result<Value, Status> {
let mut input_stream = CodedInputStream::from_bytes(&*proto_bytes);
proto_to_json_by_is(msg_name, service_api_descriptor, &mut input_stream)
}