Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I implement Sized, Serialize/Deserialize functions on Any and Send Traits?

Tags:

rust

serde

I got an issue while implement serializing/deserializing and sizing functionalities on a struct that have complex data types like Arc pointers Mutex locks. First I've resolved these Arc and Mutex serialization/deserialization problem using this topic:

How do I serialize or deserialize an Arc<T> in Serde?

but now, I got stuck on implementing ser/desr and sizing for Any and Send traits, and I have neither an idea nor a compiling example to solve this issue.

Code is here:

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;

use serde::Serialize;
use std::sync::Mutex;
use std::sync::Arc;
use std::any::Any;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
    pub id: u64,
    pub data: Arc<Mutex<Any + Send>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Data {
    pub name: String,
}

impl Data {
    fn new(name_parameter: String) -> Data {
        let data = Data {
            name: name_parameter,
        };
        data
    }
}

fn main() {
    let msg: Message = Message { id: 23, data: (Arc::new(Mutex::new(Data::new(String::from("TesData"))))) };
    let ser_msg = serde_json::to_string(&msg).unwrap();
    let des_msg: Message = serde_json::from_str(&ser_msg).unwrap();

    println!("{:?}", msg);
    println!("{:?}", ser_msg);
    println!("{:?}", des_msg);
}

Here is the code in the Playground

It gives the following errors:

error[E0277]: the size for values of type `(dyn std::any::Any + std::marker::Send + 'static)` cannot be known at compilation time
  --> src/main.rs:15:5
   |
15 |     pub data: Arc<Mutex<Any + Send>>,
   |     ^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `(dyn std::any::Any + std::marker::Send + 'static)`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required because of the requirements on the impl of `serde::Serialize` for `std::sync::Mutex<(dyn std::any::Any + std::marker::Send + 'static)>`
   = note: required because of the requirements on the impl of `serde::Serialize` for `std::sync::Arc<std::sync::Mutex<(dyn std::any::Any + std::marker::Send + 'static)>>`
   = note: required by `serde::ser::SerializeStruct::serialize_field`

error[E0277]: the trait bound `(dyn std::any::Any + std::marker::Send + 'static): serde::Serialize` is not satisfied
  --> src/main.rs:15:5
   |
15 |     pub data: Arc<Mutex<Any + Send>>,
   |     ^^^ the trait `serde::Serialize` is not implemented for `(dyn std::any::Any + std::marker::Send + 'static)`
   |
   = note: required because of the requirements on the impl of `serde::Serialize` for `std::sync::Mutex<(dyn std::any::Any + std::marker::Send + 'static)>`
   = note: required because of the requirements on the impl of `serde::Serialize` for `std::sync::Arc<std::sync::Mutex<(dyn std::any::Any + std::marker::Send + 'static)>>`
   = note: required by `serde::ser::SerializeStruct::serialize_field`

error[E0277]: the trait bound `(dyn std::any::Any + std::marker::Send + 'static): serde::Deserialize<'_>` is not satisfied
  --> src/main.rs:15:5
   |
15 |     pub data: Arc<Mutex<Any + Send>>,
   |     ^^^ the trait `serde::Deserialize<'_>` is not implemented for `(dyn std::any::Any + std::marker::Send + 'static)`
like image 238
RustGear Avatar asked Nov 15 '18 08:11

RustGear


People also ask

What does it mean to serialize and deserialize data?

Data serialization is the process of converting an object into a stream of bytes to more easily save or transmit it. The reverse process—constructing a data structure or object from a series of bytes—is deserialization.

What is serialize and deserialize in C?

Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called deserialization.

What does deserialize mean in programming?

Deserialization is the process of reconstructing a data structure or object from a series of bytes or a string in order to instantiate the object for consumption. This is the reverse process of serialization, i.e., converting a data structure or object into a series of bytes for storage or transmission across devices.


1 Answers

You can use this solution as a work around but it should work it out for you i guess.

You have to access the data: Arc<Mutex<Any + Send>> then serialize/deserialze data and id separately.

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;

use serde::Serialize;
use std::sync::Mutex;
use std::sync::Arc;
use std::any::Any;

#[derive(Debug, Clone)]
pub struct Message {
    pub id: u64,
    pub data: Arc<Mutex<Any + Send>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Data {
    pub name: String,
}

impl Data {
    fn new(name_parameter: String) -> Data {
        let data = Data {
            name: name_parameter,
        };
        data
    }
}

fn main() {
    let msg: Message = Message { id: 23, data: (Arc::new(Mutex::new(Data::new(String::from("TesData"))))) };
    let _id = msg.id;
    let guard = msg.data.lock().unwrap();
    let msg_data: Option<&Data> = guard.downcast_ref::<Data>();
    let ser_msg_data = serde_json::to_string(&msg_data).unwrap();
    let des_msg_data: Data = serde_json::from_str(&ser_msg_data).unwrap();
    println!("{:?}", des_msg_data);
    let des_msg:Message = Message {id : _id, data: Arc::new(Mutex::new(des_msg_data))};
    println!("{:?}", msg);
    println!("{:?}", ser_msg_data);
    println!("{:?}", des_msg);

}

Here is the playground. Playground

like image 139
Alican Beydemir Avatar answered Sep 21 '22 15:09

Alican Beydemir