英文:
How do you propagate errors in a Rust serde serializer?
问题
I'm here to help with the translation. Here's the translated code portion:
我正在尝试实现 serde 的 [serialize_with ](https://serde.rs/field-attrs.html) 属性。
我有以下代码:
```rust
use serde::Serializer;
pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let string = serde_json::to_string(json).unwrap();
s.serialize_str(&string)
}
我不喜欢倒数第二行的 unwrap()
。但我无法弄清如何将 to_string
返回的错误转换为 S::Error
。
我尝试用类似以下的代码替换 let
行:
let string = serde_json::to_string(json)?;
我得到了以下错误:
error[E0277]: `?` 无法将错误转换为 `<S as serde::Serializer>::Error`
--> src/model/field_type.rs:30:45
|
26 | pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
| ----------------------- 预期是 `<S as serde::Serializer>::Error` 因为这个原因
...
30 | let string = serde_json::to_string(json)?;
| ^ 问题号操作 (`?`) 隐式地使用 `From` 特性对错误值执行转换
| 注意:为了实现 `Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>`,需要执行 `FromResidual<Result<Infallible, serde_json::Error>>`
help: 考虑进一步限制关联类型
|
28 | S: Serializer, <S as serde::Serializer>::Error: From<serde_json::Error>
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
有关此错误的更多信息,请尝试 `rustc --explain E0277`。
还尝试将整个内容替换为以下代码:
match serde_json::to_string(json) {
Ok(string) => s.serialize_str(&string),
Err(e) => Err(e.into()),
}
类似的错误:
error[E0277]: 没有满足 `<S as serde::Serializer>::Error: From<serde_json::Error>` 的特性约束
--> src/model/field_type.rs:32:25
|
32 | Err(e) => Err(e.into()),
| ^^^^ 没有为 `<S as serde::Serializer>::Error` 实现 `From<serde_json::Error>` 的特性
|
= 注意:为了使 `serde_json::Error` 实现 `Into<<S as serde::Serializer>::Error>` 需要的特性约束
help: 考虑进一步限制关联类型
|
28 | S: Serializer, <S as serde::Serializer>::Error: From<serde_json::Error>
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
有关此错误的更多信息,请尝试 `rustc --explain E0277`。
由于我不拥有 Serde,我假设我无法实现 into
,因此我需要某种手动转换。我无法弄清楚它的具体实现方式。
<details>
<summary>英文:</summary>
I'm trying to implement serde's [serialize_with ](https://serde.rs/field-attrs.html) attribute.
I have this code:
```rust
use serde::Serializer;
pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let string = serde_json::to_string(json).unwrap();
s.serialize_str(&string)
}
I don't like the unwrap()
on the second to last line. But I can't figure out how to convert the error that to_string
returns into S::Error
.
I've tried replacing the let
line with something like:
let string = serde_json::to_string(json)?;
And I got:
error[E0277]: `?` couldn't convert the error to `<S as serde::Serializer>::Error`
--> src/model/field_type.rs:30:45
|
26 | pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
| ----------------------- expected `<S as serde::Serializer>::Error` because of this
...
30 | let string = serde_json::to_string(json)?;
| ^ the trait `From<serde_json::Error>` is not implemented for `<S as serde::Serializer>::Error`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required for `Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>` to implement `FromResidual<Result<Infallible, serde_json::Error>>`
help: consider further restricting the associated type
|
28 | S: Serializer, <S as serde::Serializer>::Error: From<serde_json::Error>
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For more information about this error, try `rustc --explain E0277`.
And also tried replacing the whole thing with:
match serde_json::to_string(json) {
Ok(string) => s.serialize_str(&string),
Err(e) => Err(e.into()),
}
Similar error:
error[E0277]: the trait bound `<S as serde::Serializer>::Error: From<serde_json::Error>` is not satisfied
--> src/model/field_type.rs:32:25
|
32 | Err(e) => Err(e.into()),
| ^^^^ the trait `From<serde_json::Error>` is not implemented for `<S as serde::Serializer>::Error`
|
= note: required for `serde_json::Error` to implement `Into<<S as serde::Serializer>::Error>`
help: consider further restricting the associated type
|
28 | S: Serializer, <S as serde::Serializer>::Error: From<serde_json::Error>
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For more information about this error, try `rustc --explain E0277`.
Since I don't own Serde, I assume I can't implement into
, so I need some kind of manual conversion. I couldn't figure out what that would look like.
答案1
得分: 6
The error is not a serde error, but you can wrap it in a serde custom error like so:
use serde::{Serializer, ser::Error};
pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let string = serde_json::to_string(json).map_err(S::Error::custom)?;
s.serialize_str(&string)
}
Note that you need to import serde::ser::Error
as that's the trait where the custom
function comes from.
英文:
The error is not a serde error, but you can wrap it in a serde custom error like so:
use serde::{Serializer, ser::Error};
pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let string = serde_json::to_string(json).map_err(S::Error::custom)?;
s.serialize_str(&string)
}
Note that you need to import serde::ser::Error
as that's the trait where the custom
function comes from.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论