标签: serde-json

使用 serde 以字符串形式获取枚举变量的名称

我正在尝试获取枚举变体的名称,作为字符串 serde 期望/创建的名称。例如,假设我有以下枚举:

#[derive(Serialize, Deserialize)]
#[serde(rename_all="camelCase")]
pub enum SomeEnum {
    WithoutValue,
    withValue(i32),
}
Run Code Online (Sandbox Code Playgroud)

那么我怎样才能获得变体的 serde 名称呢?就像是

serde::key_name(SomeEnum::WithoutValue) // should be `withoutValue`
serde::key_name(SomeEnum::WithValue)    // should be `withValue`
Run Code Online (Sandbox Code Playgroud)

serde_json对于没有值的变体,我可以使用 , 进行黑客攻击:

serde_json::to_string(SomeEnum::WithoutValue).unwrap(); // yields `"withoutValue"` with quotation marks
Run Code Online (Sandbox Code Playgroud)

这不是最好的解决方案,因为我需要去掉引号,但在技术上可以工作。

更糟糕的是当枚举变量具有值时。它变得更加混乱。

serde_json::to_string(SomeEnum::WithValue(0)).unwrap(); // yields `"{\"second\":0}"
Run Code Online (Sandbox Code Playgroud)

有没有一种干净的方法来实现这一目标?我找不到 serde API 来获取字符串形式的键名。

rust serde serde-json

13
推荐指数
1
解决办法
1万
查看次数

创建返回实现serde :: Deserialize的值的函数时的生命周期错误

我正在使用serde和serde_json 1.0来解码base64字符串中的数据:

fn from_base64_str<T: Deserialize>(string: &str) -> T {
    let slice = decode_config(string, URL_SAFE).unwrap();     
    serde_json::from_slice(&slice).unwrap()
}
Run Code Online (Sandbox Code Playgroud)

当我编译时,我得到了这个:

error[E0106]: missing lifetime specifier
 --> src/main.rs:6:23
  |
6 | fn from_base64_str<T: Deserialize>(string: &str) -> T {
  |                       ^^^^^^^^^^^ expected lifetime parameter
Run Code Online (Sandbox Code Playgroud)

检查serde doc,Deserialize定义为:

pub trait Deserialize<'de>: Sized {
Run Code Online (Sandbox Code Playgroud)

所以我添加了生命周期:

fn from_base64_str<'de, T: Deserialize<'de>>(string: &str) -> T {
    let slice = decode_config(string, URL_SAFE).unwrap();     
    serde_json::from_slice(&slice).unwrap()
}
Run Code Online (Sandbox Code Playgroud)

然后编译器告诉我:

error: `slice` does not live long enough
  --> src/main.rs:11:29
   |
11 |     serde_json::from_slice(&slice).unwrap()
   |                             ^^^^^ does …
Run Code Online (Sandbox Code Playgroud)

lifetime rust serde serde-json

12
推荐指数
2
解决办法
1420
查看次数

如何使用 serde_json 动态构建 json 数组或对象?

我需要在运行时构建一个 json 对象。现在,只是一个简单的 {"key": "stringvalue"} 对象。但每个键/值对必须添加到循环中。

这看起来非常简单/基本,但我没有找到任何好的示例或文档。我终于设法让一些东西发挥作用,但它似乎太复杂了,不是正确的方法。

任何人都可以发布一个工作示例吗?

rust serde serde-json

9
推荐指数
1
解决办法
8437
查看次数

如何将所有字段默认值的类型反序列化为None?

我必须反序列化JSON blob,在某些地方,缺少整个对象被编码为具有相同结构的对象,但其所有字段都设置为默认值(空字符串和零).

extern crate serde_json; // 1.0.27
#[macro_use] extern crate serde_derive; // 1.0.78
extern crate serde; // 1.0.78

#[derive(Debug, Deserialize)]
struct Test<T> {
    text: T,
    number: i32,
}

#[derive(Debug, Deserialize)]
struct Outer {
    test: Option<Test<String>>,
}

#[derive(Debug, Deserialize)]
enum Foo { Bar, Baz }
#[derive(Debug, Deserialize)]
struct Outer2 {
    test: Option<Test<Foo>>,
}

fn main() {
    println!("{:?}", serde_json::from_str::<Outer>(r#"{ "test": { "text": "abc", "number": 42 } }"#).unwrap());
    // good: Outer { test: Some(Test { text: "abc", number: 42 }) }

    println!("{:?}", serde_json::from_str::<Outer>(r#"{ …
Run Code Online (Sandbox Code Playgroud)

json rust serde serde-json

7
推荐指数
1
解决办法
242
查看次数

在 Rust 中将 JSON 解析为 Map

我是 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

一旦我尝试运行此代码,编译器就会抛出以下错误:

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
   |
   = …
Run Code Online (Sandbox Code Playgroud)

rust serde-json

7
推荐指数
1
解决办法
3699
查看次数

当大小写不匹配时,如何反序列化枚举?

我有一个 JSON 结构,如下所示:

{ "type": "suite", "event": "started", "test_count": 1 }
Run Code Online (Sandbox Code Playgroud)

我想反序列化为这些结构:

#[derive(Debug, Deserialize)]
enum ResultType {
    Suite,
    Test,
}

#[derive(Debug, Deserialize)]
enum ResultEvent {
    Started,
    Failed,
    Ok,
}

#[derive(Debug, Deserialize)]
struct JsonResult {
    #[serde(rename(deserialize = "type"))]
    test_type: ResultType,
    event: ResultEvent,
    test_count: Option<u32>,
}
Run Code Online (Sandbox Code Playgroud)

我找不到让 serde_json 使用正确大小写的方法。我不断收到这些错误:

{ "type": "suite", "event": "started", "test_count": 1 }
Run Code Online (Sandbox Code Playgroud)

如果我将枚举值的大小写更改为全部小写或全部大写,则它可以工作,但我希望能够使用 PascalCase。

rust serde serde-json

7
推荐指数
3
解决办法
2099
查看次数

Rust 使用 Reqwest 处理错误响应体

我在 Rust 应用程序中使用reqwest(version 0.10.4) 包进行 HTTP 调用,但找不到任何有关如何处理可能返回多个可能的响应正文(主要用于错误处理)的 API 调用的示例。

例如,API 调用可以使用成功的 JSON 结构或以下格式的错误结构进行响应:

{
    "errors": ["..."]
}
Run Code Online (Sandbox Code Playgroud)

目前我有该函数的代码,但似乎无法弄清楚如何struct根据 HTTP 请求是否成功来确定我需要将响应缓冲区反序列化到哪个缓冲区。

use super::responses::{Error, Response};
use crate::clients::HttpClient;
use crate::errors::HttpError;
use reqwest::header;

pub fn call() -> Result<Response, HttpError> {
    let url = format!("{}/auth/userpass/login/{}", addr, user);
    let response = HttpClient::new()
        .post(&url)
        .header(header::ACCEPT, "application/json")
        .header(header::CONTENT_TYPE, "application/json")
        .json(&serde_json::json!({ "password": pass }))
        .send();

    match response {
        Ok(res) => {
            let payload = res.json(); // could be `Error` or `Response` but only parses …
Run Code Online (Sandbox Code Playgroud)

rust serde-json reqwest

7
推荐指数
1
解决办法
2515
查看次数

如何使用 serde_json 从 JSON 数组内部流式传输元素?

我有一个 5GB JSON 文件,它是具有固定结构的对象数组:

[
  {
    "first": "John",
    "last": "Doe",
    "email": "john.doe@yahoo.com"
  },
  {
    "first": "Anne",
    "last": "Ortha",
    "email": "anne.ortha@hotmail.com"
  },
  ....
]
Run Code Online (Sandbox Code Playgroud)

我知道我可以尝试使用如何使用 Serde 使用顶级数组反序列化 JSON?中所示的代码来解析此文件。:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
struct User {
    first: String,
    last: String,
    email: String,
}

let users: Vec<User> = serde_json::from_str(file)?;
Run Code Online (Sandbox Code Playgroud)

有多个问题:

  1. 首先将其作为一个字符串整体读取
  2. 读取为字符串后,它将其转换为结构向量User(我不想要这样)

我尝试了如何从 Rust 中的文件/流中延迟读取多个 JSON 值?但它会在打印任何内容之前读取整个文件,并在循环内立即打印整个结构。我期待循环中一次有一个对象:

在此输入图像描述

理想情况下,(已解析的)用户对象的解析和处理应该在两个单独的线程/任务/例程中同时发生,或者通过使用通道同时发生。

rust serde-json

7
推荐指数
1
解决办法
2595
查看次数

在 Rust 中使用 return 语句和省略分号有什么区别?

我正在编写一个函数,该函数在成功(和失败)时返回 serde_json::Value。以前在 Rust 中,我一直省略分号以从函数返回数据,如下面的代码示例所示:

use serde_json::{Result, Value};
use core::result::Result as ResultCore;

fn returning_function() -> ResultCore<Value, Value> {
    let data = r#"
    {
        "status": "ok",
        "response": {
            "data": "secret message!"
         }
    }
    "#;

    match str_to_json(data) {
        Ok(json_data) => match json_data["status"].as_str() {
            Some(status_str) => {
                if status_str == "ok" {
                    Ok(json_data["response"].clone())
                }
            }
            None => eprintln!("\"status\" was not a string")
        }
        Err(error) => eprintln!("something went wrong! here's what: {}", error)
    }

    Err(serde_json::Value::Null)
}

fn str_to_json(json_data: &str) -> Result<Value> {
    Ok(serde_json::from_str(json_data)?)
}
Run Code Online (Sandbox Code Playgroud)

这是我不明白的部分:这不能编译。Rust …

return rust serde-json

6
推荐指数
2
解决办法
664
查看次数

您如何使 Serde 结构同时处理借用和拥有的数据?

我想制作一个能够从借用数据 ( serde_json::from_str) 或拥有数据 ( serde_json::from_reader)反序列化的 Serde 结构。我已经阅读了理解反序列化器生命周期,并且我理解了两个特征边界(<'de, T> where T: Deserialize<'de><T> where T: DeserializeOwned)之间的区别;我想要的是一个实现两个特征边界的结构,这样它就可以从任一反序列化函数中使用。

以下代码(playground)拒绝编译:

use serde_json; // 1.0.56
use serde; // 1.0.114
use std::fs;
use std::io;
use std::borrow::Cow;

#[derive(serde::Deserialize)]
struct Resource<'s> {
    // The Cow should allow for either borrowed or owned data
    #[serde(borrow)]
    pub foo: Cow<'s, str>,
}

fn main() {
    {
        // Works as expected when referencing a string...
        let s = "{\"foo\":\"bar\"}";
        let resource: Resource …
Run Code Online (Sandbox Code Playgroud)

rust serde serde-json

6
推荐指数
1
解决办法
242
查看次数

标签 统计

rust ×10

serde-json ×10

serde ×6

json ×1

lifetime ×1

reqwest ×1

return ×1