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

Rust遍历JSON键值对填充HashMap时遇序列化错误

Rust处理JSON时serde_json与ajson跨库类型兼容问题解决

问题场景

从PHP转Rust,通过实战项目学习,需要处理运行时JSON文件,提取indinces部分数据并重构格式。当前代码混用ajson和serde_json库,出现编译错误。

当前代码

use {
    std::{
        fs::*,
        path::Path,
        collections::{HashMap},
    },
    ajson::*,
    serde_json::*,
    
}

pub async fn process() -> HashMap<String, Object> {
    let mut return_hash: HashMap<String, Object> = HashMap::new();
    let path = "./downloadFolder/APIReturn/a33562.json";
    let json = &std::fs::read_to_string(path).expect("Unable to read file");

    let default_map = ajson::get(json, "Defaults.Settings").expect("JSON was not well-formatted");
    let indince_map = ajson::get(json, "indinces").expect("JSON was not well-formatted");


    let mut loop_count = 0;
    for (key, value) in serde_json::json!(indince_map){
         return_hash.insert(key.to_string(), indince::new(key, value));
    }
    // 原代码缺少return语句,此处补充完整
    return_hash
}

目标JSON结构

{
    "Defaults":{
        "settings": {
             "Angle": 90,
             "Region": "27B",
             "Area": 187
        }
    },
    "indinces": {
        "Springfield": {
             "Angle": 45,
             "Area": 285
        }, 
        "Lawrence": {
             "Region": "38A"
        }
    }
}

报错信息

for (key, value) in serde_json::json!(indince_map){
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                         |
    |                         the trait `Serialize` is not implemented for `ajson::Value<'_>`
    |                         required by a bound introduced by this call

问题原因

serde_json::json!宏要求传入参数实现Serialize trait,但ajson::Value类型并未实现该trait,跨库类型不兼容导致无法直接转换。

解决方案

方案一:统一使用serde_json处理(推荐)

放弃混用ajson,全程用serde_json解析和操作JSON,避免跨库类型冲突:

use std::{
    fs::read_to_string,
    collections::HashMap,
};
use serde_json::{Value, Map};

pub async fn process() -> HashMap<String, Map<String, Value>> {
    let mut return_hash = HashMap::new();
    let path = "./downloadFolder/APIReturn/a33562.json";
    let json_str = read_to_string(path).expect("Unable to read file");
    let json: Value = serde_json::from_str(&json_str).expect("JSON was not well-formatted");

    // 提取默认设置(按需保留)
    let default_map = json["Defaults"]["settings"].clone();

    // 提取indinces并遍历
    if let Value::Object(indinces) = &json["indinces"] {
        for (key, value) in indices {
            let obj = indince::new(key.as_str(), value);
            return_hash.insert(key.clone(), obj);
        }
    }

    return_hash
}

方案二:使用ajson自身的遍历方法

若坚持使用ajson,可将indince_map转换为ajson::Object后直接遍历:

use {
    std::{
        fs::read_to_string,
        collections::HashMap,
    },
    ajson::{self, Object, Value},
};

pub async fn process() -> HashMap<String, Object> {
    let mut return_hash = HashMap::new();
    let path = "./downloadFolder/APIReturn/a33562.json";
    let json_str = read_to_string(path).expect("Unable to read file");

    let default_map = ajson::get(&json_str, "Defaults.settings").expect("JSON was not well-formatted");
    let indince_map = ajson::get(&json_str, "indinces").expect("JSON was not well-formatted");

    // 将ajson::Value转换为Object并遍历
    if let Value::Object(indinces) = indince_map {
        for (key, value) in indices {
            if let Value::Object(obj) = value {
                return_hash.insert(key, obj);
            }
        }
    }

    return_hash
}

补充说明

  • Rust类型系统严格,跨库类型无法隐式转换,处理JSON时建议统一使用一个库(serde_json是Rust生态最常用的JSON处理库,优先推荐)
  • 原代码存在拼写错误:indince应为indices(复数形式),建议修正避免后续混淆

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:13:14