我正在使用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) 在涉及自定义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) 我的代码:
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引用?为什么需要所有权?我该如何解决?
我有以下对象:
{
"data": {
"id": 1,
"name": "South America",
"countries": {
"data": [
{
"id": 122,
"name": "Brazil",
"capital": "Brasilia"
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想定义两个结构体Continent和Country,省略data不增加价值的包装。
我想将一个相当深的 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)
当然,可以实现自定义反序列化,但我想知道是否有默认的方法来实现这一点。
我正在尝试实现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) 我已经成功地用于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_str和serde_json::to_string,以轻松(反)序列化该结构。
但是,我现在还想支持serde_ini将 INI 文件序列化(反序列化)到相同的 Rust 数据结构。但我真的不知道该怎么做。
结构本身很简单,但我的具体问题在于属性:
#[serde(rename)]和#[serde(rename_all)]属性,但我不确定在哪里或如何解决。#[serde(flatten)] 似乎不适用于的serde_ini全字符串值,它需要#[serde(deserialize_with="from_str)]"所有非字符串值的属性,但这显然只适用于 INI 值,而不适用于 JSON 值。 …我正在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对键进行排序?
我有一个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) 可以像这样传递一个整数数组:
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)