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

Mandatory value accessors

Open marmeladema opened this issue 3 years ago • 4 comments

Hello and thank you for your work!

I am working on a project that uses a capnproto schema where most of the values are mandatory when reading a message. I got bitten multiple times by the fact that a reader.get_field() method for a field @0 :Text member will return an empty string when field is not specified in the message. Indeed I am now using reader.has_field() with the following pattern:

let key = if reader.has_key() {
    reader.get_key()?
} else {
    return Err(::capnp::Error::failed("Missing `key` parameter".to_owned()));
};

This is rather cumbersome to do everywhere and I wonder if the API could be improved. Would it make sense to add a new error type that could be called MissingValue (I don't care much about the actual name) and add a new try_get_<name> methods in readers to retrieve a value if it exist and fail otherwise without ever returning a default value if one hasn't been specified in the schema.

The sounds fine in principle but get_<name> reader methods already return a Resultwhich means both methods would have the same prototype, only proper documentation would differentiate them:

  • get_<name> methods will return a value, and sometime a default one for types that have an implicitly defined value like Text or integer fields
  • try_get_<name> methods will only return a value when it is present in the message

Thank you for taking the time to read me. Maybe my solution is totally off but the ergonomic issues are real though :)

marmeladema avatar Jan 04 '22 09:01 marmeladema

If we consider that capnpproto-rust errors are "low-level" errors maybe instead of adding a new error type that is mostly about application implementation, we could add opt_get_<name methods that would return an Option?

marmeladema avatar Jan 07 '22 17:01 marmeladema

Some other cases where this is would be useful are get_data_field and get_bool_field.

Imagine the case where a schema has an added data or boolean field. If the data is not present those routines return Zero::zero and false respectively.

In these cases it may be desirable for the application code to detect and handle the case where the data is not present.

xcthulhu avatar Mar 05 '22 16:03 xcthulhu

My preferred way to do this would be to add an annotation in rust.capnp to allow individual fields to opt in to getting wrapped in std::Option in the generated code.

dwrensha avatar Mar 06 '22 15:03 dwrensha

@dwrensha we are hoping to switch to capnproto at my work. Since the capnproto format is extensible, we want to add fields to our data-structures over time. We are excited to have this feature.

I am still coming up to speed with this codebase. Could you give some pointers on how to get started implementing what you have in mind?

xcthulhu avatar Mar 06 '22 23:03 xcthulhu