你如何在Rust的serde序列化器中传播错误?

huangapple go评论84阅读模式
英文:

How do you propagate errors in a Rust serde serializer?

问题

I'm here to help with the translation. Here's the translated code portion:

  1. 我正在尝试实现 serde [serialize_with ](https://serde.rs/field-attrs.html) 属性。
  2. 我有以下代码:
  3. ```rust
  4. use serde::Serializer;
  5. pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
  6. where
  7. S: Serializer,
  8. {
  9. let string = serde_json::to_string(json).unwrap();
  10. s.serialize_str(&string)
  11. }

我不喜欢倒数第二行的 unwrap()。但我无法弄清如何将 to_string 返回的错误转换为 S::Error

我尝试用类似以下的代码替换 let 行:

  1. let string = serde_json::to_string(json)?;

我得到了以下错误:

  1. error[E0277]: `?` 无法将错误转换为 `<S as serde::Serializer>::Error`
  2. --> src/model/field_type.rs:30:45
  3. |
  4. 26 | pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
  5. | ----------------------- 预期是 `<S as serde::Serializer>::Error` 因为这个原因
  6. ...
  7. 30 | let string = serde_json::to_string(json)?;
  8. | ^ 问题号操作 (`?`) 隐式地使用 `From` 特性对错误值执行转换
  9. | 注意:为了实现 `Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>`,需要执行 `FromResidual<Result<Infallible, serde_json::Error>>`
  10. help: 考虑进一步限制关联类型
  11. |
  12. 28 | S: Serializer, <S as serde::Serializer>::Error: From<serde_json::Error>
  13. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  14. 有关此错误的更多信息,请尝试 `rustc --explain E0277`

还尝试将整个内容替换为以下代码:

  1. match serde_json::to_string(json) {
  2. Ok(string) => s.serialize_str(&string),
  3. Err(e) => Err(e.into()),
  4. }

类似的错误:

  1. error[E0277]: 没有满足 `<S as serde::Serializer>::Error: From<serde_json::Error>` 的特性约束
  2. --> src/model/field_type.rs:32:25
  3. |
  4. 32 | Err(e) => Err(e.into()),
  5. | ^^^^ 没有为 `<S as serde::Serializer>::Error` 实现 `From<serde_json::Error>` 的特性
  6. |
  7. = 注意:为了使 `serde_json::Error` 实现 `Into<<S as serde::Serializer>::Error>` 需要的特性约束
  8. help: 考虑进一步限制关联类型
  9. |
  10. 28 | S: Serializer, <S as serde::Serializer>::Error: From<serde_json::Error>
  11. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  12. 有关此错误的更多信息,请尝试 `rustc --explain E0277`

由于我不拥有 Serde,我假设我无法实现 into,因此我需要某种手动转换。我无法弄清楚它的具体实现方式。

  1. <details>
  2. <summary>英文:</summary>
  3. I&#39;m trying to implement serde&#39;s [serialize_with ](https://serde.rs/field-attrs.html) attribute.
  4. I have this code:
  5. ```rust
  6. use serde::Serializer;
  7. pub fn serialize_json_as_string&lt;S&gt;(json: &amp;serde_json::value::Value, s: S) -&gt; Result&lt;S::Ok, S::Error&gt;
  8. where
  9. S: Serializer,
  10. {
  11. let string = serde_json::to_string(json).unwrap();
  12. s.serialize_str(&amp;string)
  13. }

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:

  1. let string = serde_json::to_string(json)?;

And I got:

  1. error[E0277]: `?` couldn&#39;t convert the error to `&lt;S as serde::Serializer&gt;::Error`
  2. --&gt; src/model/field_type.rs:30:45
  3. |
  4. 26 | pub fn serialize_json_as_string&lt;S&gt;(json: &amp;serde_json::value::Value, s: S) -&gt; Result&lt;S::Ok, S::Error&gt;
  5. | ----------------------- expected `&lt;S as serde::Serializer&gt;::Error` because of this
  6. ...
  7. 30 | let string = serde_json::to_string(json)?;
  8. | ^ the trait `From&lt;serde_json::Error&gt;` is not implemented for `&lt;S as serde::Serializer&gt;::Error`
  9. |
  10. = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
  11. = note: required for `Result&lt;&lt;S as serde::Serializer&gt;::Ok, &lt;S as serde::Serializer&gt;::Error&gt;` to implement `FromResidual&lt;Result&lt;Infallible, serde_json::Error&gt;&gt;`
  12. help: consider further restricting the associated type
  13. |
  14. 28 | S: Serializer, &lt;S as serde::Serializer&gt;::Error: From&lt;serde_json::Error&gt;
  15. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16. For more information about this error, try `rustc --explain E0277`.

And also tried replacing the whole thing with:

  1. match serde_json::to_string(json) {
  2. Ok(string) =&gt; s.serialize_str(&amp;string),
  3. Err(e) =&gt; Err(e.into()),
  4. }

Similar error:

  1. error[E0277]: the trait bound `&lt;S as serde::Serializer&gt;::Error: From&lt;serde_json::Error&gt;` is not satisfied
  2. --&gt; src/model/field_type.rs:32:25
  3. |
  4. 32 | Err(e) =&gt; Err(e.into()),
  5. | ^^^^ the trait `From&lt;serde_json::Error&gt;` is not implemented for `&lt;S as serde::Serializer&gt;::Error`
  6. |
  7. = note: required for `serde_json::Error` to implement `Into&lt;&lt;S as serde::Serializer&gt;::Error&gt;`
  8. help: consider further restricting the associated type
  9. |
  10. 28 | S: Serializer, &lt;S as serde::Serializer&gt;::Error: From&lt;serde_json::Error&gt;
  11. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  12. 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:

  1. use serde::{Serializer, ser::Error};
  2. pub fn serialize_json_as_string<S>(json: &serde_json::value::Value, s: S) -> Result<S::Ok, S::Error>
  3. where
  4. S: Serializer,
  5. {
  6. let string = serde_json::to_string(json).map_err(S::Error::custom)?;
  7. s.serialize_str(&string)
  8. }

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:

  1. use serde::{Serializer, ser::Error};
  2. pub fn serialize_json_as_string&lt;S&gt;(json: &amp;serde_json::value::Value, s: S) -&gt; Result&lt;S::Ok, S::Error&gt;
  3. where
  4. S: Serializer,
  5. {
  6. let string = serde_json::to_string(json).map_err(S::Error::custom)?;
  7. s.serialize_str(&amp;string)
  8. }

Note that you need to import serde::ser::Error as that's the trait where the custom function comes from.

huangapple
  • 本文由 发表于 2023年6月29日 10:21:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76577699.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定