You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中将serde_json::Value转换为prost_types::Struct?

实现serde_json::Value到prost_types::Struct的转换及可用Crate推荐

手动实现方案

你可以通过递归处理serde_json::Value的不同变体,将其映射为prost_types对应的类型:

use prost_types::{Struct, Value, ListValue};
use serde_json::{Value as JsonValue, Map};

fn to_struct(json: JsonValue) -> Struct {
    let mut fields = std::collections::BTreeMap::new();
    
    if let JsonValue::Object(obj) = json {
        for (key, val) in obj {
            fields.insert(key, to_prost_value(val));
        }
    }
    
    Struct { fields }
}

fn to_prost_value(json_val: JsonValue) -> Value {
    match json_val {
        JsonValue::Null => Value { kind: Some(Value::Kind::NullValue(0)) },
        JsonValue::Bool(b) => Value { kind: Some(Value::Kind::BoolValue(b)) },
        JsonValue::Number(num) => {
            if let Some(int_val) = num.as_i64() {
                Value { kind: Some(Value::Kind::Int64Value(int_val)) }
            } else if let Some(uint_val) = num.as_u64() {
                Value { kind: Some(Value::Kind::Uint64Value(uint_val)) }
            } else if let Some(float_val) = num.as_f64() {
                Value { kind: Some(Value::Kind::DoubleValue(float_val)) }
            } else {
                // 处理无法识别的数字类型,默认转为Null
                Value { kind: Some(Value::Kind::NullValue(0)) }
            }
        },
        JsonValue::String(s) => Value { kind: Some(Value::Kind::StringValue(s)) },
        JsonValue::Array(arr) => {
            let values = arr.into_iter().map(to_prost_value).collect();
            Value { kind: Some(Value::Kind::ListValue(ListValue { values })) }
        },
        JsonValue::Object(obj) => {
            let struct_val = to_struct(JsonValue::Object(obj));
            Value { kind: Some(Value::Kind::StructValue(struct_val)) }
        },
    }
}

代码说明

  • to_struct专门处理JSON对象,将键值对转换为Struct的fields集合
  • to_prost_value递归处理所有JSON值类型:
    • 布尔值、字符串直接映射到对应Protobuf类型
    • 数字优先尝试转为整数类型,再降级为浮点数
    • JSON数组转为ListValue,嵌套对象递归转为Struct
    • Null值对应Protobuf的NullValue

现成Crate方案

可以直接使用prost-json这个Crate,它封装了完整的转换逻辑:

步骤1:添加依赖

在Cargo.toml中加入:

[dependencies]
prost-json = "0.4"
serde_json = "1.0"
prost-types = "0.12"

步骤2:使用转换方法

use prost_json::ValueExt;
use serde_json::Value as JsonValue;
use prost_types::Struct;

fn to_struct(json: JsonValue) -> Struct {
    json.into()
}

prost-json实现了From/Into trait,直接通过类型转换就能完成双向映射,无需手动处理递归逻辑。

内容的提问来源于stack exchange,提问作者Yang Bo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:27:15