Rust - serde/bincode serializacia/deserializacia dat

Ink

  • ****
  • 436
    • Zobrazit profil
    • E-mail
Re:Rust - serde/bincode serializacia/deserializacia dat
« Odpověď #30 kdy: 21. 12. 2021, 12:34:06 »
OP: Došel jsi prosímtě k něčemu? Zafungoval Ti ten "untagged"?


Re:Rust - serde/bincode serializacia/deserializacia dat
« Odpověď #31 kdy: 21. 12. 2021, 19:49:16 »
OP: Došel jsi prosímtě k něčemu? Zafungoval Ti ten "untagged"?

Zdar, ano, untagged je nakoniec uzitocne makro :)
Nakolko Rust len skumam, tak som sa nepustal do zbytocnych zlozitosti... vsak sa bude refaktorovat.

Je to +- ok, ked bude cas, tak dvojity matach() blok nahradim makrom, tak isto by slo nahradit aj "pub fn value(&self) -> MessageBodyType" ako makro.. mozno casom

Kód: [Vybrat]
use serde_repr::*;
use serde::{Deserialize, Serialize};

#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[serde(untagged)]
#[repr(u8)]
pub enum MessageBodyType {
    Version = 11,
    BatteryHealth = 22,
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub enum MessageBody {
    Version(Version),
    BatteryHealth(BatteryHealth),
}

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
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Message {
    header: MessageHeader,
    body: MessageBody,
}

impl Message {
    pub fn serialize_body(mb: MessageBody) -> Result<Vec<u8>, Error> {

        let mut body_vec: Vec<u8>;
        match &mb {
            MessageBody::Version(v) => {
                body_vec = bincode::serialize(&v)?;
            },
            MessageBody::BatteryHealth(h) => {
                body_vec = bincode::serialize(&h)?;
            }
        }

        let header : MessageHeader = MessageHeader {
            message_type: mb.value(),
            _pad0: HEADER_PAD,
            body_size: body_vec.len() as u32,
            crc: 0,
        };

        let mut header_vec = bincode::serialize(&header)?;
        header_vec.append(&mut body_vec);

        Ok(header_vec)
    }

    pub fn deserialize_body<'a>(bytes: &'a [u8]) -> Result<MessageBody, Error> {
        if bytes.len() < std::mem::size_of::<MessageHeader>(){
            return Err(());
        }

        let message_header_len = std::mem::size_of::<MessageHeader>();

        match header.message_type {
            MessageBodyType::Version => {
                let version: Version = bincode::deserialize(&bytes[message_header_len..bytes.len()])?;
                return Ok(MessageBody::Version(version));
            },   
            MessageBodyType::BatteryHealth => {
                let battery: BatteryHealth = bincode::deserialize(&bytes[message_header_len..bytes.len()])?;
                return Ok(MessageBody::BatteryHealth(battery));
            }
        }
    }
}

#[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})).unwrap();
    let serialized_battery: Vec<u8> = Message::serialize(MessageBody::BatteryHealth(BatteryHealth{x1: 10, x2: 20, x3: 0x0A0A})).unwrap();

    let deserialized_version: MessageBody = Message::deserialize(&serialized_version).unwrap();


  Ok(())
}