- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
包含Box作为成员变量的结构:
type Item = dyn Fn() -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
struct Inner {
pub data: Box<Item>,
}
// a function, like the type: Item
fn parse() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("parse called");
Ok(())
}
现在出现的问题是,自定义实现对struct
Inner
进行反序列化的反序列化:
let s = r#"{"data": "parse"}"#;
转换为struct内部:
{
data: Box::new(parse)
}
我知道
serde
不会为
Box<T>
实现反序列化,而必须手动实现Deserialize,这是我的代码,遵循
docmentaion给出的示例:
use serde::de::{self, Deserialize, Deserializer, MapAccess, Visitor};
use std::fmt;
type Item = dyn Fn() -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
struct Inner {
pub data: Box<Item>,
}
fn parse() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("parse called");
Ok(())
}
impl<'de> Deserialize<'de> for Inner {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
enum Field {
Data,
};
impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`data` only")
}
fn visit_str<E>(self, value: &str) -> Result<Field, E>
where
E: de::Error,
{
match value {
"data" => Ok(Field::Data),
_ => Err(de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
struct InnerVisitor;
impl<'de> Visitor<'de> for InnerVisitor {
type Value = Inner;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Inner")
}
fn visit_map<V>(self, mut map: V) -> Result<Inner, V::Error>
where
V: MapAccess<'de>,
{
let mut data = None;
while let Some(key) = map.next_key()? {
match key {
Field::Data => {
if data.is_some() {
return Err(de::Error::duplicate_field("data"));
}
data = Some(map.next_value()?);
}
}
}
let data = data.ok_or_else(|| de::Error::missing_field("data"))?;
//
// do something on the `data` and finally return a Item-like function (***)
//
Ok(Inner {
data: Box::new(parse),
}) // (***)
}
}
const FIELDS: &'static [&'static str] = &["data"];
deserializer.deserialize_struct("Inner", FIELDS, InnerVisitor)
}
}
fn main() {
let s = r#"{"data": "parse"}"#;
let inner: Inner = serde_json::from_str(s).unwrap();
}
但是,当我运行这些代码时,会出现错误:
Compiling playground v0.0.1 (/playground)
warning: unused variable: `inner`
--> src/main.rs:93:9
|
93 | let inner: Inner = serde_json::from_str(s).unwrap();
| ^^^^^ help: if this is intentional, prefix it with an underscore: `_inner`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `data`
--> src/main.rs:76:21
|
76 | let data = data.ok_or_else(|| de::Error::missing_field("data"))?;
| ^^^^ help: if this is intentional, prefix it with an underscore: `_data`
warning: 2 warnings emitted
Finished dev [unoptimized + debuginfo] target(s) in 1.12s
Running `target/debug/playground`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: string \"parse\", expected unit", line: 1, column: 16)', src/main.rs:93:48
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
粗略地讲,我猜问题出在该块的
(***)
中,但不知道如何解决。如何为我的用例正确实现
Deserialize
?
最佳答案
该警告提示您:您没有使用数据,因此Rust不在乎Option内的类型。其实我很惊讶它正在编译。由于使用serdes默认类型,Rust假定您期望()
,而您期望String
。根本不会消耗您的数据,所以只需执行以下操作:
let mut data: Option<&str> = None;
另外,我建议您将所有
Field
实现替换为:
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Data,
}
(由于未知原因,此堆栈在
playground上溢出,但是我希望这是操场上的问题)
use serde::{Deserialize, Deserializer};
type Item = dyn Fn() -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
#[derive(Deserialize)]
struct Inner {
#[serde(deserialize_with = "deserialize_data")]
pub data: Box<Item>,
}
fn deserialize_data<'de, D>(d: D) -> Result<Box<Item>, D::Error>
where
D: Deserializer<'de>,
{
let data = <&str>::deserialize(d)?;
println!("{}", data);
Ok(Box::new(parse))
}
fn parse() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("parse called");
Ok(())
}
fn main() {
let s = r#"{"data": "parse"}"#;
let inner: Inner = serde_json::from_str(s).unwrap();
}
这是更好的方法,因为通过Serde宏实现比纯朴的实现要好得多。
关于rust - 使用Box对结构进行反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64780981/
考虑这样的代码: trait Foo { fn foo(&self); } fn consume_func(b: Box>) { unimplemented!(); } fn prod
考虑这样的代码: trait Foo { fn foo(&self); } fn consume_func(b: Box>) { unimplemented!(); } fn prod
我不明白在 Rust 中,当我们 Box 父结构时,结构中的结构发生了什么。 struct Outer1 { child: Inner1, } struct Inner1 { n: i
我将开始开发一个新网站,并准备处理浏览器用于计算元素宽度和高度的不同方法 (box model stuff)。不知何故,我想到了:如果我只是将 box-sizing 应用于网站中的所有元素会怎么样?
在 java 应用程序中使用 box java sdk 访问 box api 时,我遇到了下面提到的错误。请指出此问题的原因。 Exception in thread "main" com.box.s
计算盒子的宽高时,outline width like outline: 5px dashed red; 如果 box-sizing:border-box,框的宽度/高度是否会考虑轮廓? 最佳答案 我
读完the subtyping chapter of the Nomicon ,我无法理解类型参数的协方差。特别是对于 Box类型,描述为:T is covariant . 但是,如果我写这段代码:
给定这段代码: trait Trait {} struct Child; impl Trait for Child {} struct Father { child: &'a Box, } i
与文件 chooser for dropbox 类似,box.com 有没有? 最佳答案 Box 目前不维护自己的“文件选择器”;然而,有一个很棒的服务叫做 filepicker.io,它充当几乎所有
感谢您对我的问题的回复:Is this a bug of Box API v2 when getting events 这是一个与此相关的新问题。问题是我不能可靠地使用从以前的调用中获得的 next_
我试图让 Box Enterprise API 使用 As-User 工作。我有一个管理员帐户,我用它来尝试检索子帐户中的内容。 我首先使用管理员帐户检索子帐户的用户ID。并将用户 ID 添加为字段“
我想在一个简单的导轨中本地查看我的 Box 帐户中的图像 app .目标是使用这些图像进行幻灯片放映。我寻找必要的参数来传递每个图像相关 url成标签。看来我只能下载图像,或从 Box 应用程序中查看
这个问题在这里已经有了答案: Why doesn't Rust support trait object upcasting? (5 个答案) 关闭 4 年前。 给定代码 trait Base {
所以基本上我尝试从https://github.com/Gor-Ren/gym-jsbsim转换这个自定义健身房环境。使用farama基金会的gymnasium api。这是我正在处理的存储库:htt
我是BOX API的新手,因此正在使用API的v2。我正在从我的应用程序本地进行REST调用。 我想上传一个以前可能上传或未上传的文件。我知道父文件夹ID和文件名。我需要覆盖现有文件,或者至少要再
我已被授予访问(协作)文件夹的权限。我需要的是每天访问该文件夹并从中获取文件。现在我生成的开发者 token 将在 1 小时后过期。有什么办法可以得到authorization code没有第一站,它
我正在尝试将 Box 中上传的文件与另一个外部系统同步。我使用哪些 API 来获取“在给定 dd/mm/yy hh:mm:ss 后上传/更新的所有文件的列表”? 干杯! 最佳答案 我认为User Ev
Vagrant 文档和 CLI 使用术语“box”和“base box”。命名意味着基本框是一种特定类型的框,但是,这些术语似乎被用作同义词。 Vagrant“盒子”和 Vagrant“基础盒子”之间
Box 允许您为文件夹创建标签,但如何从 API 中获取该信息?我在 GET /folders/{id} API 中没有看到标签返回.标签也不被视为元数据。 最佳答案 如果你看看 Fields wri
我正在尝试确定应该使用哪个版本的 Box api。我的决定取决于 v1 api 的 EOL 时间线。我不想完成我的应用程序,就在应用程序发布之前(或之后不久),v1 api 停止工作。 我很乐意使用
我是一名优秀的程序员,十分优秀!