标签: serde

创建返回实现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序列化和反序列化的通用函数?

在涉及自定义Serde(1.0)序列化和反序列化方法的项目中,我依靠此测试例程来检查序列化对象和返回是否会产生等效对象.

// let o: T = ...;
let buf: Vec<u8> = to_vec(&o).unwrap();
let o2: T = from_slice(&buf).unwrap();
assert_eq!(o, o2);
Run Code Online (Sandbox Code Playgroud)

这样的内联工作非常好.我对可重用性的下一步是check_serde为此目的发挥作用.

pub fn check_serde<T>(o: T)
where
    T: Debug + PartialEq<T> + Serialize + DeserializeOwned,
{
    let buf: Vec<u8> = to_vec(&o).unwrap();
    let o2: T = from_slice(&buf).unwrap();
    assert_eq!(o, o2);
}
Run Code Online (Sandbox Code Playgroud)

这适用于拥有类型,但不适用于具有生命周期边界的类型(Playground):

check_serde(5);
check_serde(vec![1, 2, 5]);
check_serde("five".to_string());
check_serde("wait"); // [E0279]
Run Code Online (Sandbox Code Playgroud)

错误:

error[E0279]: the requirement `for<'de> 'de : ` is not satisfied (`expected bound lifetime parameter 'de, found concrete lifetime`)
  --> …
Run Code Online (Sandbox Code Playgroud)

serialization lifetime rust serde

12
推荐指数
1
解决办法
625
查看次数

为什么serde_json :: from_reader取得了读者的所有权?

我的代码:

fn request_add<T>(request: &mut Request, collection_name: &'static str) -> Fallible<Fallible<String>>
where
    T: serde::Serialize + serde::de::DeserializeOwned,
{
    let add_dao = dao::MongoDao::new(collection_name);
    let obj = serde_json::from_reader::<Body, T>(request.body)?; //cannot move out of borrowed content
    Ok(add_dao.add(&obj))
}
Run Code Online (Sandbox Code Playgroud)

我有一个cannot move out of borrowed content错误,因为request是一个参考,但为什么不serde_json::from_reader使用mut引用?为什么需要所有权?我该如何解决?

json rust serde

12
推荐指数
1
解决办法
302
查看次数

使用 Serde 反序列化对象时,有没有办法省略包装器/根对象?

我有以下对象:

{
  "data": {
    "id": 1,
    "name": "South America",
    "countries": {
      "data": [
        {
          "id": 122,
          "name": "Brazil",
          "capital": "Brasilia"
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我想定义两个结构体ContinentCountry,省略data不增加价值的包装。

rust serde

12
推荐指数
1
解决办法
2310
查看次数

rust serde - 反序列化时展平路径

我想将一个相当深的 JSON 反序列化为 Rust 结构:

{
  "root": {
    "f1": {
      "f2": {
         "f3": 123
       }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

推导时Deserialize,我将不得不创建太多的结构 - 对于上述 JSON 的每个级别一个:

struct Root {
  f1: Field1
}
struct Field1 {
  f2: Field2
}
struct Field3 {
  f3: Field3
}
// ...
Run Code Online (Sandbox Code Playgroud)

有什么方法可以避免拥有这么多的结构。我没有找到任何对派生有帮助的属性。我想要这样的东西:

struct Root {
  // some attr?
  f3: u64
}
Run Code Online (Sandbox Code Playgroud)

当然,可以实现自定义反序列化,但我想知道是否有默认的方法来实现这一点。

json rust serde

12
推荐指数
1
解决办法
1842
查看次数

如何为外部类型实现 serde 的序列化和反序列化特征?

我正在尝试实现Serialize外部Deserialize枚举,但我不知道如何实现。它有From<u64>所以我想做的只是让该对象序列化。

#[derive(Serialize, Deserialize)]
pub struct ImageBinds {
    binds: HashMap<KeybdKey, Vec<u8>>, // KeybdKey doesn't implement serialize
}

// won't compile with this:
// only traits defined in the current crate can be implemented for arbitrary types
// impl doesn't use only types from inside the current crate
// I understand the orphan rule and all that but I have no idea how else I'd implement it
// I've looked at serde remote stuff and I …
Run Code Online (Sandbox Code Playgroud)

rust serde

12
推荐指数
1
解决办法
5393
查看次数

使用 serde 实现两种(反)序列化格式

我已经成功地用于serde_json反序列化和序列化 JSON。我的设置看起来有点像这样(非常简单):

use serde::{Deserialize, Serialize};
use serde_json;
use serde_with::skip_serializing_none;

#[skip_serializing_none]
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct Foo {
    #[serde(flatten)]
    bar: Option<Bar>,
    
    baz_quux: Option<u8>,
}

#[skip_serializing_none]
#[derive(Deserialize, Serialize)]
struct Bar {
    #[serde(rename = "plughXyzzySomeRandomStuff")]
    plugh_xyzzy: Option<u8>
}
Run Code Online (Sandbox Code Playgroud)

然后我实现了FromStrand Displayon Foo,它依次调用serde_json::from_strserde_json::to_string,以轻松(反)序列化该结构。

但是,我现在还想支持serde_ini将 INI 文件序列化(反序列化)到相同的 Rust 数据结构。但我真的不知道该怎么做。

结构本身很简单,但我的具体问题在于属性:

  • 这些键在 JSON 和 INI 格式中的命名方式不同(JSON 格式使用惯用的驼峰命名法,而 INI 则没有),因此我必须以其他方式解决#[serde(rename)]#[serde(rename_all)]属性,但我不确定在哪里或如何解决。
  • #[serde(flatten)] 似乎不适用于serde_ini全字符串值,它需要#[serde(deserialize_with="from_str)]"所有非字符串值的属性,但这显然只适用于 INI 值,而不适用于 JSON 值。 …

rust serde

12
推荐指数
1
解决办法
2813
查看次数

如何使用serde进行序列化时对HashMap键进行排序?

我正在HashMap用serde 序列化,就像这样:

#[derive(Serialize, Deserialize)]
struct MyStruct {
    map: HashMap<String, String>
}
Run Code Online (Sandbox Code Playgroud)

HashMap密钥的顺序是未指定的,并且由于散列是随机的(参见文档),因此密钥实际上最终会在相同的运行之间以不同的顺序出现.

我希望我HashMap按照排序(例如字母)键顺序进行序列化,以便序列化是确定性的.

我可以使用a BTreeMap而不是a HashMap来实现这一点,因为BTreeMap::keys()它按排序顺序返回它的键,但我宁愿不改变我的数据结构只是为了适应序列化逻辑.

如何HashMap在序列化之前告诉serde对键进行排序?

rust serde

11
推荐指数
1
解决办法
2342
查看次数

二进制(de)序列化[u8; 128]

我有一个struct包含字节数组,我想序列化和反序列化二进制文件.但它仅适用于最多32个元素的数组.

这是我的最小示例代码

main.rs:

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;

use bincode::{serialize, deserialize, Infinite};

const BYTECOUNT: usize = 32; // 33 and more does not work, I need 128
type DataArr = [u8; BYTECOUNT];

#[derive(Serialize, Deserialize, Debug)]
struct Entry {
    number: i64,
    data: DataArr
}

fn main() {
    let mut my_entry = Entry { number: 12345, data: [0; BYTECOUNT] };
    my_entry.data[4] = 42;

    // Convert the Entry to binary.
    let serialized: Vec<u8> …
Run Code Online (Sandbox Code Playgroud)

arrays serialization rust deserialization serde

11
推荐指数
1
解决办法
630
查看次数

如何将一组对象传递给WebAssembly并将其转换为带有wasm-bindgen的结构向量?

可以像这样传递一个整数数组:

const js = import("./webassembly_rust");
let array_nums = [1,2,3,4,5,6,7,8,9];

js.then(js => {
  js.test( array_nums );
}); 
Run Code Online (Sandbox Code Playgroud)

到WebAssembly并将其保存在这样的向量中:

extern crate serde_json;
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[macro_use]
extern crate serde_derive;

#[wasm_bindgen]
pub fn test(array: JsValue) {
    let elements: Vec<u32> = array.into_serde().unwrap();
}
Run Code Online (Sandbox Code Playgroud)

也可以像这样传递一个对象:

const js = import("./webassembly_rust");
let jsObject = {name: "hello world", id: "99", parent_id: "11"};

js.then(js => {
  js.test( jsObject );
}); 
Run Code Online (Sandbox Code Playgroud)

到WebAssembly并将其保存为这样的Element结构:

extern crate serde_json;
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[macro_use]
extern crate serde_derive;

#[derive(Serialize, Deserialize)] …
Run Code Online (Sandbox Code Playgroud)

rust webassembly serde wasm-bindgen

11
推荐指数
1
解决办法
1709
查看次数