deku icon indicating copy to clipboard operation
deku copied to clipboard

write_map or similar to map the value before writing (opposite of map attribute)

Open passcod opened this issue 3 years ago • 1 comments

This is the way I write it at the moment:

use deku::prelude::*;
use std::ffi::CString;

#[derive(Clone, Debug, DekuRead, DekuWrite)]
struct Foo {
		#[deku(
			map = "from_nul_terminated",
			writer = "CString::new(handle.to_vec()).unwrap().write(deku::output, ())"
		)]
		handle: Vec<u8>,
}

fn from_nul_terminated(raw: CString) -> Result<Vec<u8>, DekuError> {
	Ok(raw.into_bytes())
}

That works, but requires me to take care to write the correct writer every time (the field mention changes, in particular), and also I can't return an error?

I'd like to do e.g.

use deku::prelude::*;
use std::ffi::CString;

#[derive(Clone, Debug, DekuRead, DekuWrite)]
struct Foo {
		#[deku(
			map = "from_nul_terminated",
			map_write = "to_nul_terminated"
		)]
		handle: Vec<u8>,
}

fn from_nul_terminated(raw: CString) -> Result<Vec<u8>, DekuError> {
	Ok(raw.into_bytes())
}

fn to_nul_terminated(cooked: Vec<u8>) -> Result<CString, DekuError> {
	CString::new(cooked.to_vec()).map_err(...)
}

This is something that pops up for more than nul-terminated things, too, hence the general map_write instead of special-support for nul-termination (though that could be nice); this example is just what I've been struggling through tonight.

passcod avatar Jul 15 '21 07:07 passcod

I agree, there's some attributes which only make sense for read. I wonder if there's a better way to describe this.

sharksforarms avatar Jul 21 '21 14:07 sharksforarms