@ryanofsky do I understand correctly that for the .capnp
there’s no difference when making something an std::optional
?
It depends on the type. In capnproto schemas primitive fields (numbers, bools, enums, unions) are not optional and are always present. If these fields are not assigned values they are just initialized to 0. So to represent a std::optional<T> value where T is a primitive you have to change the capnproto schema to be able to represent std::nullopt differently somehow, unless you are ok with std::nullopt being represented as 0.
Capnproto does allow non-primitive fields (data, text, struct, list fields) to be missing so you don’t need to change the capnproto schema to use std::optional for these. For these fields a std::nullopt field is just serialized with the field unset, and this is not ambiguous.
The difference between primitive/non-primitve fields is explained at https://capnproto.org/faq.html#how-do-i-make-a-field-optional and the faq recommends using a union with Void to represent optional primitive fields(*). Unfortunately though, I didn’t know about that trick and I don’t think libmultiprocess currently supports that, although it could. Another natural way to represent an optional value might just to use a List() type and only populate it with 0 or 1 elements.
But actually the way I’ve supported optional primitive fields in libmultiprocess so far has just been to accompany them with a boolean “has” field. So for example the Chain::getHeight
method which returns std::optional<int>
in c++ returns (result :Int32, hasResult :Bool)
in capnproto. I know this works for parameters and returns values, though I’m not sure if it works for struct fields. You could just declare the struct to have a hasFeeThreshold: Bool
value and I could fix this in libmultiprocess if it isn’t working.
Or if we think maybe List(Int64)
or Union(Void, Int64)
would be better ways to represent std::optional<Int64>
fields we could use one of those representations and I can extend libmultiprocess to support them.
(*) I think the faq might be a little buggy, though, because I believe the Void field needs to come before the Int32 field in its example for Void to be the default value instead of 0.. EDIT: NVM faq is actually fine. I forgot the schema language allows setting default values so as long as the default value is void this is fine