HiveBrain v1.2.0
Get Started
← Back to all entries
snippetrustModerateCanonical

How to convert 'struct' to '&[u8]'?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
converthowstruct

Problem

I want to send my struct via a TcpStream. I could send String or u8, but I can not send an arbitrary struct. For example:

struct MyStruct {
    id: u8,
    data: [u8; 1024],
}

let my_struct = MyStruct { id: 0, data: [1; 1024] };
let bytes: &[u8] = convert_struct(my_struct); // how??
tcp_stream.write(bytes);


After receiving the data, I want to convert &[u8] back to MyStruct. How can I convert between these two representations?

I know Rust has a JSON module for serializing data, but I don't want to use JSON because I want to send data as fast and small as possible, so I want to no or very small overhead.

Solution

(Shamelessly stolen and adapted from Renato Zannon's comment on a similar question)

Perhaps a solution like bincode would suit your case? Here's a working excerpt:

Cargo.toml

[package]
name = "foo"
version = "0.1.0"
authors = ["An Devloper "]
edition = "2018"

[dependencies]
bincode = "1.0"
serde = { version = "1.0", features = ["derive"] }


main.rs

use serde::{Deserialize, Serialize};
use std::fs::File;

#[derive(Serialize, Deserialize)]
struct A {
    id: i8,
    key: i16,
    name: String,
    values: Vec,
}

fn main() {
    let a = A {
        id: 42,
        key: 1337,
        name: "Hello world".to_string(),
        values: vec!["alpha".to_string(), "beta".to_string()],
    };

    // Encode to something implementing `Write`
    let mut f = File::create("/tmp/output.bin").unwrap();
    bincode::serialize_into(&mut f, &a).unwrap();

    // Or just to a buffer
    let bytes = bincode::serialize(&a).unwrap();
    println!("{:?}", bytes);
}


You would then be able to send the bytes wherever you want. I assume you are already aware of the issues with naively sending bytes around (like potential endianness issues or versioning), but I'll mention them just in case ^_^.

Code Snippets

[package]
name = "foo"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"

[dependencies]
bincode = "1.0"
serde = { version = "1.0", features = ["derive"] }
use serde::{Deserialize, Serialize};
use std::fs::File;

#[derive(Serialize, Deserialize)]
struct A {
    id: i8,
    key: i16,
    name: String,
    values: Vec<String>,
}

fn main() {
    let a = A {
        id: 42,
        key: 1337,
        name: "Hello world".to_string(),
        values: vec!["alpha".to_string(), "beta".to_string()],
    };

    // Encode to something implementing `Write`
    let mut f = File::create("/tmp/output.bin").unwrap();
    bincode::serialize_into(&mut f, &a).unwrap();

    // Or just to a buffer
    let bytes = bincode::serialize(&a).unwrap();
    println!("{:?}", bytes);
}

Context

Stack Overflow Q#28127165, score: 36

Revisions (0)

No revisions yet.