我的程序解析了足够大的 json 文档(30MB),在 CPU 速度较慢的机器上需要 70 毫秒,我想加快这个过程,我发现 27% 的解析发生在我的foo_document_type_deserialize
.有没有办法在String
这里跳过分配:let s = String::deserialize(deserializer)?;
?
我完全确定表示枚举值的字符串不包含特殊的 json 字符,例如\b \f \n \r \t \" \\
,因此使用未转义的字符串应该是安全的。
use serde::{Deserialize, Deserializer};
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FooDocument {
// other fields...
#[serde(rename = "type")]
#[serde(deserialize_with = "foo_document_type_deserialize")]
doc_type: FooDocumentType,
}
fn foo_document_type_deserialize<'de, D>(deserializer: D) -> Result<FooDocumentType, D::Error>
where
D: Deserializer<'de>,
{
use self::FooDocumentType::*;
let s = String::deserialize(deserializer)?;
match s.as_str() {
"tir lim bom bom" => Ok(Var1), …
Run Code Online (Sandbox Code Playgroud) 我用来通过网络序列化的结构的定义
pub struct NetworkData {
id: String,
status: String,
details: <Data Structure>,
}
Run Code Online (Sandbox Code Playgroud)
现在有一个函数接受这个结构,将其序列化并通过网络发送。
fn send_data(data: NetworkData ...) -> ... {
let data = serde_json::to_string(&data).expect("serialize issue");
let mut request = Request::new(reqwest::Method::POST, url);
*request.body_mut() = Some(data.into());
self.inner
.execute(request)
...
}
Run Code Online (Sandbox Code Playgroud)
现在我想通过网络发送“x-www-form-urlencoded”数据,这应该更改此功能如下:-
fn send_data(data: NetworkData ...) -> ... {
// How should I change this?????
//let data = serde_json::to_string(&data).expect("serialize issue");
let mut request = Request::new(reqwest::Method::POST, url);
let content_type = HeaderValue::from_str(&format!("{}", "application/x-www-form-urlencoded",))
.expect("Header value creation bug");
request
.headers_mut()
.insert(header::CONTENT_TYPE, content_type);
*request.body_mut() = Some(data.into()); …
Run Code Online (Sandbox Code Playgroud) 我一直在试图建立以下配置的serialport
拉斯特箱用serde
,这样我就可以直观地提供7
在我的配置了data_bits
,但它会被反序列化serialport::DataBits::Seven
。不幸的是,当我希望它是数字 ( 7
) 而不是字符串 ( seven
) 时,它似乎失败了。
货物.toml
[package]
name = "serde_error"
version = "0.1.0"
authors = ["Jason Miller"]
edition = "2018"
[dependencies]
serialport = "3.3.0"
serde = { version = "1.0", features = ["derive"] }
ron = "0.5.1"
Run Code Online (Sandbox Code Playgroud)
以下结果导致错误:
[package]
name = "serde_error"
version = "0.1.0"
authors = ["Jason Miller"]
edition = "2018"
[dependencies]
serialport = "3.3.0"
serde = { version = "1.0", features = ["derive"] …
Run Code Online (Sandbox Code Playgroud) 尝试cargo build
针对此代码:
#![allow(unused)]
use serde::{Deserialize, Serialize};
use serde_json::{Result, Value};
#[derive(Serialize, Deserialize,Debug)]
struct Repository{
r#type: String,
url: String,
}
fn main() {
println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)
这是 cargo.toml 文件:
[package]
name = "demo_err"
version = "0.1.0"
authors = ["Onorio Catenacci <catenacci@ieee.org>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = "1.0.104"
serde_json = "1.0.44"
Run Code Online (Sandbox Code Playgroud)
当然,我的真实代码要大一些,但这是我可以重现错误的最小代码。
我收到以下错误:
Compiling demo_err v0.1.0 (U:\skunkworks\rust\demo_err)
error: cannot find derive macro `Serialize` in this scope
--> src\main.rs:9:10
|
9 | …
Run Code Online (Sandbox Code Playgroud) 我使用 Serde 反序列化用 YAML 编写的自定义配置文件。该文件可以包含各种类型的定义,我表示为内部标记的枚举:
OfKindFoo:
kind: Foo
bar: bar;
baz: baz;
OfKindQux:
kind: Qux
quux: qux;
Run Code Online (Sandbox Code Playgroud)
我用 Rust 表示它是这样的:
#[derive(Deserialize)]
#[serde(tag = "kind")]
enum Definition {
Foo(Foo),
Qux(Qux),
}
#[derive(Deserialize)]
struct Foo {
bar: String,
baz: String,
}
#[derive(Deserialize)]
struct Qux {
quux: String,
}
Run Code Online (Sandbox Code Playgroud)
我希望用户能够kind
完全省略该字段,并且当它被省略时,Serde 应该默认将其反序列化为Foo
.
我开始Deserialize
在Definition
. 我正在尝试将其反序列化为映射并查找kind
键并根据此键以及它是否存在返回相应的枚举变体。
我需要以某种方式将其他地图字段的反序列化分别“转发”到Foo::deserialize
或Bar::deserialize
。fn deserialize
只接受一个参数,即Deserializer
. 有没有办法将地图“转换”为解串器或以其他方式获得在该特定地图上“开始”的解串器?
我无法使用,#[serde(other)]
因为它返回Err
缺少标签。即使没有,文档也指出other
只能应用于“单元变体”,即不包含任何数据的变体。
我是 rust 的新手,并尝试在 stackoverflow 中搜索以及阅读 serde 文档 https://docs.serde.rs/serde/trait.Serialize.html和https://serde.rs/impl-serialize.html,但我有点失落。
我想使用 Tera 生成 html,而我传递给它的结构没有serde::ser::Serialize
实现trait ,我试图实现它,但它看起来不太正确。
Cargo.toml 依赖项
serde = "1.0.115"
serde_derive = "1.0.115"
serde-xml-rs = "0.4.0"
tera = "0.7.2"
Run Code Online (Sandbox Code Playgroud)
主文件
extern crate tera;
#[macro_use]
extern crate serde_derive;
extern crate serde;
use tera::Context;
use serde::ser::{Serialize, SerializeStruct, Serializer};
#[derive(Serialize, Debug)]
struct Person {
firstname: String,
lastname: String,
age: i32,
}
#[derive(Debug)]
struct Attendees {
people: Vec<Person>,
updatedOn: String,
updatedBy: String,
}
impl Serialize for Attendees {
fn serialize<S>(&self, serializer: …
Run Code Online (Sandbox Code Playgroud) use serde_derive::Deserialize; // 1.0.118
use toml; // 0.5.8
#[derive(Debug, Deserialize)]
struct Remote {
enabled: bool,
address: String,
}
#[derive(Debug, Deserialize)]
struct Config {
remote: Option<Remote>,
}
fn main() {
let config: Config = toml::from_str(r#"
[remote]
enabled = true
address = "example.com"
"#).unwrap();
println!("{:?}", config);
let config: Config = toml::from_str(r#"
[remote]
enabled = false
address = "example.com"
"#).unwrap();
println!("{:?}", config);
// How to make `config.remote` `None` ?
}
Run Code Online (Sandbox Code Playgroud)
我希望 的其余字段Remote
是可选的,并且Config::remote
当设置为 falseNone
时。enabled
我尝试了tag …
我正在尝试编写一个自定义Deserialize
实现,它可以对我的枚举执行不区分大小写的反序列化:
use serde::{Deserialize, Deserializer}; // 1.0.120
use serde_json; // 1.0.61
#[derive(Debug, PartialEq)]
enum MyEnum {
Foo,
Bar,
}
// Implements case-insensitive deserialization of node types using from_str above
impl<'de> Deserialize<'de> for MyEnum {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let v = String::deserialize(deserializer)?;
match v.to_ascii_lowercase().as_ref() {
"foo" => Ok(MyEnum::Foo),
"bar" => Ok(MyEnum::Bar),
_ => Err(serde::de::Error::custom("invalid value")),
}
}
}
Run Code Online (Sandbox Code Playgroud)
这有效,但会导致两种分配:一种是将输入值放入 a 中String
,另一种是将其转换String
为大写。我不需要第一个,因为 serde 提供了Deserialize for &str
. 我怎么称呼它?
这不起作用: …
我用:
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct Foo {
...
}
Run Code Online (Sandbox Code Playgroud)
我想写一个自Deserialize
定义Foo
。
如何查看生成的派生Deserialize
代码serde
?我想以此为起点。
我有一个 JSON 对象,其中包含一个本身就是 JSON 对象的字符串。我怎样才能反序列化它?
我希望能够执行以下操作:
#[derive(Deserialize)]
struct B {
c: String,
d: u32,
}
#[derive(Deserialize)]
struct Test {
a: String,
b: B,
}
let object: Test = serde_json::from_str(
r#"
{
"a": "string",
"b": "{\"c\":\"c_string\",\"d\":1234}"
}
"#,
)
.unwrap();
Run Code Online (Sandbox Code Playgroud)
但这令人恐慌 invalid type: string "{\"c\":\"c_string\",\"d\":1234}", expected struct B