If I wanted to emulate the struct pack functionality in python, what would be the equivalent of:
struct.pack("!iiii"1, 0,0, 40)
Could it be achieved in the byteorder crate?
Would it be something like:
let mut bytes = Vec::with_capacity(16usize);
bytes.write_u32::<BigEndian>(1).unwrap();
bytes.write_u64::<BigEndian>(0).unwrap();
bytes.write_u32::<BigEndian>(40).unwrap();
bytes
Is there another way to do this?
Thank you.
If you are looking for a way to serialize and deserialize structs then serde is what you seek.
hwchen
3
I've used byteorder in a similar situation. I don't know if there's a better way to do it.
Thanks. I guess I'll keep doing my way. I realize that this question is a bit lacking, so I will mark it as closed.
As mentioned, the equivalent of the Python approach would be Serde. In this case together with bincode:
// [dependencies]
// bincode = "0.7"
// byteorder = "1.0"
// serde = "0.9"
extern crate bincode;
extern crate byteorder;
extern crate serde;
use bincode::Infinite;
use byteorder::BigEndian;
use serde::{Serialize, Deserialize};
// Or error_chain, or whatever strategy you are using for errors.
type Result<T> = ::std::result::Result<T, Box<::std::error::Error>>;
fn pack<T: Serialize>(data: &T) -> Result<Vec<u8>> {
use bincode::endian_choice::serialize;
let bytes = serialize::<_, _, BigEndian>(data, Infinite)?;
Ok(bytes)
}
fn unpack<T: Deserialize>(bytes: &[u8]) -> Result<T> {
use bincode::endian_choice::deserialize;
let data = deserialize::<_, BigEndian>(bytes)?;
Ok(data)
}
fn main() {
let data = (1, 0, 0, 40);
let vec = pack(&data).unwrap();
println!("{:?}", vec);
let out: (i32, i32, i32, i32);
out = unpack(&vec).unwrap();
println!("{:?}", out);
}
The pack
and unpack
functions can be re-used for any type, including structs and enums that use #[derive(Serialize, Deserialize)]
(explained here).
2 Likes