capnproto-rust icon indicating copy to clipboard operation
capnproto-rust copied to clipboard

Support newtypes

Open Kixunil opened this issue 3 years ago • 1 comments

I'm researching capnproto with intention to use it soon. From what I can see there is no support for newtypes. I believe it'd be useful.

Examples of some newtypes I have in mind:

struct Amount(u64);

struct Hash([u8; 32]);

I imagine there could be a way to annotate fields to use newtypes with specific validation function. Reader would call this function and return the newtype or error:

// defined by consumer or the crate providing Amount
fn validate_amount(buf: &[Word]) -> Result<&Amount> {
    if buf.len() != 1 {
        return Err(Error { kind: ErrorKind::Fail, message: "length is not 1".to_owned() });
    }
    if cast_word_to_u64(buf[0]) > LIMIT {
        return Err(Error { kind: ErrorKind::Fail, message: "value over limit".to_owned() });
    }
    Ok(unsafe { &*(buf.as_ptr() as *const Amount) })
}

// generated code
impl Reader<'_> {
    pub fn get_amount(&self) -> Result<&Amount> {
        // validates pointers etc
        let words = self.internal_get_amount();
        validate_amount(words)
    }
}

The consumers would just call get_amount() and get the validated newtype out of the box.

Similarly, serialization could be implemented.

Kixunil avatar Dec 22 '21 12:12 Kixunil

This seems like it would be a reasonable feature. To support it, we would add an annotation to rust.capnp

I wonder whether there might be any common ground between this and proposals for allowing automatic conversion between capnp messages and native rust structs, as described in #136

dwrensha avatar Dec 27 '21 22:12 dwrensha