higherkindness / mu-haskell

Mu (μ) is a purely functional framework for building micro services.
http://higherkindness.io/mu-haskell/
Apache License 2.0
333 stars 19 forks source link

Handling oneof that is NOT_SET #348

Open fintara opened 8 months ago

fintara commented 8 months ago

The following proto:

message MyMsg {
  bool a = 1;
  oneof b {
    bool c = 2;
    bool d = 3;
  }
}

corresponds to the following Haskell code:

data MyMsg = MyMsg
  { a :: Bool
  , b :: MyMsg_b
  }
  deriving (Eq, Show, Generic)
  deriving (ToSchema MySchema "MyMsg", FromSchema MySchema "MyMsg")

data MyMsg_b
  = MyMsg_b_c Bool
  | MyMsg_b_d Bool
  deriving (Eq, Show, Generic)

Now, according to the proto3 spec, a particular oneof may remain unset. To check this (f.e. in Python) you'd call my_msg.WhichOneof('b') - it can return None, "c" or "d".

With this library you cannot handle this very real possibility, instead you get a runtime error:

status = StatusCode.INVALID_ARGUMENT
details = "done-error: WireTypeError "unknown type in an union""
debug_error_string = "UNKNOWN:Error received from peer ipv4:127.0.0.1:21599 {grpc_message:"done-error: WireTypeError \"unknown type in an union\"", grpc_status:3, created_time:"2024-03-18T13:36:28.721508+02:00"}"

Currently it is not possible to declare the type of the b field to be Maybe MyMsg_b.

The only workaround (as I described in my previous issue #339) is to wrap the oneof in yet another message. Now I'm pretty sure this ought to be fixed.