Ahojte kolegovia, 
Tentokrat sa na Vas obraciam kvoli serializacii/deserializacii struktur(y) - jednoduchych MSG (TCP/IP) medzi serverom(Rust) a klientom C/freeRTOS(32bit MCU, 128kb RAM).
Spravy su vsehovsudy jednoduche, nieje nutne ich balit do msgpack, protobuf, bson a pod.
Na serializaciu/deserializaciu som pouzil serde/bincode, s tym ze vysledna sprava sa sklada z MessageHeader + MessageBody => Message. Na tomto designe sa mi nepacia dve veci, a to:
MessageHeader::message_type je ulozena hodnota z MessageBodyType::{Version, BatteryHealth} a sucastne Message::body obsahuje {enum MessageBody::Version(Version), enum BatteryHealth(BatteryHealth) }
co ma za nasledok ze Serde serializuje Message(Version) nasledovne
0             1       2      3        4
[message_type | _pad0 | body_size     ]
[              crc                    ]
[              enum                   ]      <---- serde vlozil enum
[x1           |  x2   |     x3        ]
Takze "struct MessageHeader" ma dlzku 8 bajtov, "struct Version" ma dlzku 4 bajty => idealne by "struct Message" mal mat 12 bajtov.
V skutocnosti ma "struct Message" 16 bajtov, a to z dovodu ze serde prida 4 bajty na rozlisenie enum MessageBody::{Version, BatteryHealth}
Serializovany objekt s prihladnutim na kod vyzsie vyzera nasledovne, kde 11/22 je MessageBodyType::{Version, BatteryHealth}, a 0/1 na 9 pozicii je "enum MessageBody::{Version(), BatteryHealth()}"
serialized_version: (16) vec![11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...]
serialized_battery: (16) vec![22, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, ...]
  Preto sa pytam skusenejsich, akceptovat to, ze serde prida 4bajty na rozlisenie enumu a tuto vec zohladit na strane klienta,
Pripadne, napada Vas moznost ako namodelovat kod nizsie, tak, aby serde/bincode serializovalo/deserializovalo iba mne chcenych 12bajtov (MessageHeader + MessageBody)
AD: Pokusal som sa namodelovat "pub fn deserialize<'a>(bytes: &'a [u8]) -> Box<MessageTrait>", toto sa mi nepodarilo skrz (
https://doc.rust-lang.org/error-index.html#E0038)
Rust:
    cargo - serde
    cargo - bincode
use serde_repr::*;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub enum MessageBody {
    Version(Version),
    BatteryHealth(BatteryHealth),
}
#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
pub enum MessageBodyType {
    Version = 11,
    BatteryHealth = 22,
}
impl MessageBody {
    pub fn value(&self) -> MessageBodyType {
        match *self {
            MessageBody::Version(_) => MessageBodyType::Version,
            MessageBody::BatteryHealth(_) => MessageBodyType::BatteryHealth
        }
    }
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[repr(C)]
pub struct MessageHeader {
    message_type: MessageBodyType,  // 1
    _pad0: u8,                      // 1
    body_size: u16,                 // 2
    crc: u32,                       // 4
}
impl MessageHeader {
  pub fn new_as(message_type: MessageBodyType) -> MessageHeader {
    MessageHeader {
        message_type: message_type,
        _pad0: 0,
        body_size: 0,
        crc: 0,
    }
  }
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Message {
    header: MessageHeader,
    body: MessageBody,
}
impl Message {
    pub fn serialize(mt: MessageBody) -> Vec<u8> {
        let header = MessageHeader::new_as(mt.value());
        let header_size_of = std::mem::size_of::<MessageHeader>(); 
        let header_vec =  bincode::serialize(&header).unwrap();
        let header_vec_len = header_vec.len();
        let body_version_size_of = std::mem::size_of::<Version>();
        let body_vec: Vec<u8> = bincode::serialize(&mt).unwrap();
        let body_vec_vec_len = body_vec.len();
        let message: Message = Message { header:  header, body: mt };
        let message_size_of = std::mem::size_of::<Message>();
        let message_vec = bincode::serialize(&message).unwrap();
        let message_len = message_vec.len();
        
        message_vec
    }
    pub fn deserialize<'a>(bytes: &'a [u8]) -> Message {
        let message_header_len = std::mem::size_of::<MessageHeader>();
        let header_slice: &[u8] = &bytes[0..message_header_len];
        let header: MessageHeader = bincode::deserialize(header_slice).unwrap();
        let message: Message = bincode::deserialize(bytes).unwrap();
        message
    }
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[repr(C)]
pub struct Version {
    pub x1: u8,       // 1
    pub x2: u8,       // 1
    pub x3: u16,      // 2
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[repr(C)]
pub struct BatteryHealth {
    pub x1: u8,       // 1
    pub x2: u8,       // 1
    pub x3: u16,      // 2
}
fn main () -> Result<(), Box<(dyn std::error::Error + 'static)>> {
    let serialized_version: Vec<u8> = Message::serialize(MessageBody::Version(Version{x1: 3, x2: 6, x3: 0xFAFA}));
    let serialized_battery: Vec<u8> = Message::serialize(MessageBody::BatteryHealth(BatteryHealth{x1: 10, x2: 20, x3: 0x0A0A}));
    let deserialized_version: Message = Message::deserialize(&serialized_version);
  Ok(())
}
Diky M.