Этот пример кода:

use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
struct Foo {
    bar: String,
    baz: Baz
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
enum Baz {
    Quux(u32),
    Flob,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
struct Bish {
    bash: u16,
    bosh: i8
}

fn main() -> std::io::Result<()> {
    let mut btree: BTreeMap<Foo, Bish> = BTreeMap::new();
    let foo = Foo {
        bar: "thud".to_string(),
        baz: Baz::Flob
    };
    let bish = Bish {
        bash: 1,
        bosh: 2
    };


    println!("foo: {}", serde_json::to_string(&foo)?);
    println!("bish: {}", serde_json::to_string(&bish)?);
    
    btree.insert(foo, bish);
    println!("btree: {}", serde_json::to_string(&btree)?);

    Ok(())
}

Дает вывод / ошибку времени выполнения:

foo: {"bar":"thud","baz":"Flob"}
bish: {"bash":1,"bosh":2}
Error: Custom { kind: InvalidData, error: Error("key must be a string", line: 0, column: 0) }

Я погуглил и обнаружил, что проблема в том, что сериализатор пытается написать:

{{"bar":"thud","baz":"Flob"}:{"bash":1,"bosh":2}}}

Который не является допустимым JSON, поскольку ключи должны быть строками.

Интернет говорит мне писать собственные сериализаторы.

Это не практичный вариант, так как у меня есть большое количество разных нестроковых ключей.

Как я могу сделать десериализацию serde_json в (десериализацию из):

{"{\"bar\":\"thud\",\"baz\":\"Flob\"}":{"bash":1,"bosh":2}}

Для произвольных нестроковых ключей в BTreeMap и HashMap?

1
fadedbee 19 Июл 2020 в 10:30

1 ответ

Лучший ответ

Обнаружив Rusty Object Notation, я понял, что использую RON -образный штифт в отверстие в форме JSON.

Правильным решением было использование JSON для интерфейса с внешним миром и RON для удобочитаемого локального хранилища данных.

1
fadedbee 19 Июл 2020 в 07:59