rust Serde字节无法序列化/反序列化

mrphzbgm  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(154)

我已经决定尝试使用serde进行网络包序列化,但这是一个痛苦的过程。
我根本无法序列化Enum,而且不断收到错误。我在网上也找不到可用的示例,在docrepo中都没有。
这就是为什么我在寻找:

use serde::{Serialize, Deserialize};

use super::{ClientMessage, ServerMessage};

/// The different messages that can be sent from the client to the lobby.
#[derive(Debug, Serialize, Deserialize)]
pub enum ClientToLobbyMessage {
    Quit,
    CreateRoom,
    JoinRoom(RoomId),
}

impl ClientMessage for ClientToLobbyMessage {
    fn from_bytes(bytes: &[u8]) -> Option<ClientToLobbyMessage> {
        serde_bytes::deserialize(bytes).ok()
    }
}

字符串
这会产生编译时错误:不满足特性界限ClientToLobbyMessage: serde_bytes::Deserialize<'_>
在枚举字段上方添加#[serde(with = "serde_bytes")]也不起作用:

use serde::{Serialize, Deserialize};

use super::{ClientMessage, ServerMessage};

/// The different messages that can be sent from the client to the lobby.
#[derive(Debug, Serialize, Deserialize)]
pub enum ClientToLobbyMessage {
    #[serde(with = "serde_bytes")]
    Quit,
    #[serde(with = "serde_bytes")]
    CreateRoom,
    #[serde(with = "serde_bytes")]
    JoinRoom(RoomId),
}


这将在派生宏中产生错误:此函数采用2个参数,但在Serialize上提供了1个参数,并且Deserialize不满足特征边界(): serde_bytes::Deserialize<'_>
最后,在serde_bytes包中找不到派生宏,如use serde_bytes::{Serialize, Deserialize};所示:此处导入了Serialize,但它只是一个特性,没有派生宏。
Cargo.toml文件如下所示:

[dependencies]
serde = { version = "1.0.178", features = ["derive"] }
serde_bytes = "0.11.12"


任何尝试向serde_bytes添加特性(就像我对serde所做的那样)的操作都会导致:无法为serde_bytes选择可解决此冲突错误的版本。
我真的希望我错过了一些明显的东西在这里,但我有点失望,因为我听说serde是超级容易使用。

gopyfrb3

gopyfrb31#

由于您的示例不完整,因此我将假设您的示例为:

use serde::{Deserialize, Serialize};

trait ClientMessage: Sized {
    fn from_bytes(bytes: &[u8]) -> Option<Self>;
}

/// The different messages that can be sent from the client to the lobby.
#[derive(Debug, Serialize, Deserialize)]
pub enum ClientToLobbyMessage {
    Quit,
    CreateRoom,
    JoinRoom(i32),
}

impl ClientMessage for ClientToLobbyMessage {
    fn from_bytes(bytes: &[u8]) -> Option<ClientToLobbyMessage> {
        serde_bytes::deserialize(bytes).ok()
    }
}

字符串
这就产生了一条可怕的错误消息:

error[E0277]: the trait bound `&[u8]: Deserializer<'_>` is not satisfied
   --> src\lib.rs:17:34
    |
17  |         serde_bytes::deserialize(bytes).ok()
    |         ------------------------ ^^^^^ the trait `Deserializer<'_>` is not implemented for `&[u8]`
    |         |
    |         required by a bound introduced by this call
    |
    = help: the following other types implement trait `Deserializer<'de>`:
              UnitDeserializer<E>
              U32Deserializer<E>
              _::_serde::de::value::StrDeserializer<'a, E>
              _::_serde::de::value::BorrowedStrDeserializer<'de, E>
              StringDeserializer<E>
              CowStrDeserializer<'a, E>
              BytesDeserializer<'a, E>
              BorrowedBytesDeserializer<'de, E>
            and 25 others
note: required by a bound in `serde_bytes::deserialize`
   --> C:\Users\Finomnis\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde_bytes-0.11.12\src\lib.rs:110:8
    |
107 | pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    |        ----------- required by a bound in this function
...
110 |     D: Deserializer<'de>,
    |        ^^^^^^^^^^^^^^^^^ required by this bound in `deserialize`

error[E0277]: the trait bound `&[u8]: Deserializer<'_>` is not satisfied
  --> src\lib.rs:17:9
   |
17 |         serde_bytes::deserialize(bytes).ok()
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Deserializer<'_>` is not implemented for `&[u8]`
   |
   = help: the following other types implement trait `Deserializer<'de>`:
             UnitDeserializer<E>
             U32Deserializer<E>
             _::_serde::de::value::StrDeserializer<'a, E>
             _::_serde::de::value::BorrowedStrDeserializer<'de, E>
             StringDeserializer<E>
             CowStrDeserializer<'a, E>
             BytesDeserializer<'a, E>
             BorrowedBytesDeserializer<'de, E>
           and 25 others

error[E0277]: the trait bound `ClientToLobbyMessage: serde_bytes::Deserialize<'_>` is not satisfied
   --> src\lib.rs:17:9
    |
17  |         serde_bytes::deserialize(bytes).ok()
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `serde_bytes::Deserialize<'_>` is not implemented for `ClientToLobbyMessage`
    |
    = help: the following other types implement trait `serde_bytes::Deserialize<'de>`:
              Box<serde_bytes::Bytes>
              Box<[u8]>
              serde_bytes::ByteBuf
              Cow<'a, [u8]>
              Cow<'a, serde_bytes::Bytes>
              Vec<u8>
              std::option::Option<T>
              &'a [u8]
              &'a serde_bytes::Bytes
note: required by a bound in `serde_bytes::deserialize`
   --> C:\Users\Finomnis\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde_bytes-0.11.12\src\lib.rs:109:8
    |
107 | pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    |        ----------- required by a bound in this function
108 | where
109 |     T: Deserialize<'de>,
    |        ^^^^^^^^^^^^^^^^ required by this bound in `deserialize`

error[E0277]: the trait bound `&[u8]: Deserializer<'_>` is not satisfied
  --> src\lib.rs:17:9
   |
17 |         serde_bytes::deserialize(bytes).ok()
   |         ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Deserializer<'_>` is not implemented for `&[u8]`
   |
   = help: the following other types implement trait `Deserializer<'de>`:
             UnitDeserializer<E>
             U32Deserializer<E>
             _::_serde::de::value::StrDeserializer<'a, E>
             _::_serde::de::value::BorrowedStrDeserializer<'de, E>
             StringDeserializer<E>
             CowStrDeserializer<'a, E>
             BytesDeserializer<'a, E>
             BorrowedBytesDeserializer<'de, E>
           and 25 others


您的错误在于,您将serde_bytes当作一种数据格式来使用,但实际上它不是。它似乎是serde的一个帮助程序库,用于处理字节数组类型。
正如@kmdreko所建议的,您可以改用bincode。这是一个真正的编码。
就像这样:

use serde::{Deserialize, Serialize};

trait ClientMessage: Sized {
    fn from_bytes(bytes: &[u8]) -> Option<Self>;
}

/// The different messages that can be sent from the client to the lobby.
#[derive(Debug, Serialize, Deserialize)]
pub enum ClientToLobbyMessage {
    Quit,
    CreateRoom,
    JoinRoom(i32),
}

impl ClientMessage for ClientToLobbyMessage {
    fn from_bytes(bytes: &[u8]) -> Option<ClientToLobbyMessage> {
        bincode::deserialize(bytes).ok()
    }
}

相关问题