Сериализация признака не реализована, несмотря на то, что она реализована?

#rust #serde #actix-web

#Ржавчина #serde #actix-web

Вопрос:

Я использую actix-web для создания приложения для восстановления пакетов, а затем вставки их в базу данных MongoDB. У меня есть структура

  #[derive(Serialize, Deserialize, Debug)]
    pub struct Gyro{
        /// GYRO FRONT   MIDDLE
        pub x0x800: [i32; 12],
        //A1X, A1Y, A1Z, A2X, A2Y, A2Z, G1X, G1Y, G1Z, G2X, G2Y, G2Z

        /// GYRO BACK
        pub x0x402: [i32; 4],
        //Motion_GPS_CAN, Vehicle_GPS_CAN, X_Angle_GPS, Y_Angle_GPS

        ///GYRO BACK
        pub x0x403: [i32; 4],
        //Z_Angle_GPS, X_Acceleration, Y_Acceleration, Z_Acceleration
    }
  

И у меня не было проблем при десериализации пакетов в структуру, но когда я пытаюсь сериализовать их в BSON для вставки в MongoDB, я получаю эту ошибку

 if let Ok(bson::Bson::Document(doc)) = bson::to_bson(amp;packet) {
                                                   ^^^^^^^ the trait `Serialize` is not implemented for `Json<Gyro>
  

Несмотря на то, что я правильно реализовал сериализацию в структуре, а также наличие

 use serde::{Serialize, Deserialize};
  

в ящике это просто не работает. Я даже проверил свои зависимости, используя crate tree -d
, и все они использовали одну и ту же версию serde. Вот мой cargo.toml

 [dependencies]
actix-web = "3.1.0"
env_logger = "0.7"
serde = { version = "1.0.117", features = ["derive"] }
mongodb = "1.1.1"
bson = "1.1.0"
  

Есть ли скрытая проблема, которую я, кажется, не замечаю, или есть другая проблема в зависимостях?

Ответ №1:

Проблема в том, что вы пытаетесь сериализовать значение типа Json<Gyro> , а не Gyro . Предполагая, что это actix-web Json тип, он не реализуется Serialize . Вам нужно будет либо развернуть его, используя amp;packet.into_inner() (который использует значение), либо сослаться на внутреннее значение с amp;*packet помощью или amp;packet.0 .

Комментарии:

1. Я думаю amp;packet.0 , что это более общий, поскольку он не будет потреблять излишне packet .

2. Это тоже сработало бы, это просто сводится к стилистическим предпочтениям. Я думаю into_inner , что это немного более ясно и явно, предполагая, что значение не понадобится позже. Поскольку тип также реализует Deref , его также можно использовать amp;*packet как другой способ избежать использования значения.

3. Мне нравится amp;*packet еще лучше. Я не согласен, что это стилистическая разница, и мне не нравится потреблять packet , если вам нужна только ссылка на внутреннее значение.

4. Достаточно справедливо, я отредактировал свой ответ, чтобы включить amp;*packet и amp;packet.0 .