Is there some way to get protobuf to serialize/deserialize F#\'s discriminated unions?
I\'m trying to serialize messages with protobuf. Messages are F# records and d
I've played with your very helpful generated output, and it looks like basically everything works - except the Message.MessageA
sub-types. These very nearly work - they are essentially the same as the "auto-tuple" code (a constructor that matches all members), except that auto-tuples doesn't currently apply to sub-types.
I think it should be possible to tweak the code to work automatically, by extending the auto-tuple code to work in this scenario (I'm trying to think of any possible bad side-effects of that, but I'm not seeing any). I don't have a specific time-frame, as I need to balance time between multiple projects and a full-time day-job, and a family, and volunteer work, and (etc etc).
In the short term, the following C# is sufficient to make it work, but I don't expect this will be an attractive option:
RuntimeTypeModel.Default[typeof(Message).GetNestedType("MessageA")]
.Add("item").UseConstructor = false;
RuntimeTypeModel.Default[typeof(Message).GetNestedType("MessageB")]
.Add("item").UseConstructor = false;
As an aside, the attributes here are unhelpful and should be avoided:
| [] MessageA of MessageA
| [] MessageB of MessageB
If they did anything, they would be duplicating the intent of
. If it is more convenient to specify them there, that might be interesting, though. But what I find really interesting about that is that the F# compiler completely ignores the AttributeUsageAttribute
, which for [ProtoMember]
is:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field,
AllowMultiple = false, Inherited = true)]
public class ProtoMemberAttribute {...}
Yes the F# compiler clearly stuck that (illegally) on a method:
[ProtoMember(1)]
[CompilationMapping(SourceConstructFlags.UnionCase, 0)]
public static ProtoBufTests.Message NewMessageA(ProtoBufTests.MessageA item)
naughty F# compiler!