Разбор JSON в карту в ржавчине

Я новичок в Rust и только что столкнулся с проблемой парсинга файлов JSON. Я пробовал использовать serde_json для этой задачи. Я знаю, как анализировать файл ASCII как строку и как анализировать его содержимое как Value, но мне нужен Map<String, Value> для итерации по KVP. Я не зашел слишком далеко, так как наткнулся на эталонную ошибку. Я попробовал следующий метод:

use std::fs;
use std::error::Error;
use serde_json::{Value, Map};

pub struct ConfigSerde;

impl ConfigSerde {
    pub fn read_config(path: &str) -> Result<Map<String, Value>, Box<Error>> {
        let config = fs::read_to_string(path)?;
        let parsed: Value = serde_json::from_str(&config)?;
        let obj: Map<String, Value> = parsed.as_object().unwrap();
        Ok(obj)
    }
}

Как только я попытался запустить этот код, компилятор выдал следующую ошибку:

error[E0308]: mismatched types
  --> src/config/serde.rs:11:39
   |
11 |         let obj: Map<String, Value> = parsed.as_object().unwrap();
   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `serde_json::map::Map`, found reference
   |
   = note: expected type `serde_json::map::Map<std::string::String, serde_json::value::Value>`
              found type `&serde_json::map::Map<std::string::String, serde_json::value::Value>`

Как я могу разобрать JSON на Map в ржавчине? Я открыт для использования альтернативных ящиков, хотя предпочтительнее использовать serde_json, поскольку он кажется наиболее надежным из всех.


person Gabor Farkas    schedule 30.07.2019    source источник


Ответы (1)


Поскольку as_object возвращает ссылку, а вам нужно принадлежащее значение, вам нужно будет клонировать карту. К счастью, Map предоставляет Clone реализацию, поэтому вы можете сделать это:

let obj: Map<String, Value> = parsed.as_object().unwrap().clone();
person Luke B.    schedule 30.07.2019
comment
Спасибо вам за быстрый ответ. Клонирование решило проблему. Я приму как можно скорее. - person Gabor Farkas; 31.07.2019
comment
Точно так же вы можете подумать об обновлении вашей read_config сигнатуры функции до pub fn read_config(path: &str) -> Result<Map<String, Value>, Box<dyn Error>>, чтобы удовлетворить предупреждающее сообщение компилятора: warning: trait objects without an explicit 'dyn' are deprecated. - person David Golembiowski; 19.12.2019