-
Notifications
You must be signed in to change notification settings - Fork 19
oneof
handling
#255
Comments
I think the problem is that data Options
= OptionsInfer { infer :: [Bool] }
| OptionsExplain { explain :: [Bool] }
| OptionsBatchSize { batchSize :: [Int32] } |
Thanks so much for the fast replies; i tried it with @serras solution;
i guess that this happens because the fields in the haskell data type are upper case; type InferOptMapping = '[ "InferOpt" ':-> "inferOpt"
, "ExplainOpt" ':-> "explainOpt"
, "BatchSizeOpt" ':-> "batchSizeOpt" ]
type InferOptMapping' = '[ "inferOpt" ':-> "InferOpt"
, "explainOpt" ':-> "ExplainOpt"
, "batchSizeOpt" ':-> "BatchSizeOpt" ]
data Options
= InferOpt { infer :: [Bool] }
| ExplainOpt { explain :: [Bool] }
| BatchSizeOpt { batchSize :: [Int32] }
deriving ( Generic )
deriving ( ToSchema GraknSchema "Options" )
via ( CustomFieldMapping "Options" InferOptMapping' Options)
deriving ( FromSchema GraknSchema "Options" )
via ( CustomFieldMapping "Options" InferOptMapping Options) and with but get the following error message for that:
|
You need to use the same mapping in both. |
ok so using the handling acc. to the docs type InferOptMapping = '[ "InferOpt" ':-> "inferOpt"
, "ExplainOpt" ':-> "explainOpt"
, "BatchSizeOpt" ':-> "batchSizeOpt" ]
data Options
= InferOpt { infer :: [Bool] }
| ExplainOpt { explain :: [Bool] }
| BatchSizeOpt { batchSize :: [Int32] }
deriving ( Generic )
deriving ( ToSchema GraknSchema "Options"
, FromSchema GraknSchema "Options" )
via ( CustomFieldMapping "Options" InferOptMapping Options) still results in
could that be connected to Protocol Buffers Field Identifiers that are not yet present in the code? if so, how would i specify them for this |
I am quite surprised by the original definition, to be honest. Those |
I am confused with the semantics of this notation too; so just something along the lines of this? data Options =
Options { inferOpt :: [Bool]
, explainOpt :: [Bool]
, batchSizeOpt :: [Int32] }
deriving ( Generic
, ToSchema GraknSchema "Options"
, FromSchema GraknSchema "Options" ) how would this mapping roughly look like? without a mapping the build error looks like this (if that helps)
|
My gut feeling is that you are in the right direction, but there might be some missing instances for the case in which the union has a single element. Let me investigate a bit more, I'll try to report back soon. |
Ok, there are some issues I found. First of all, the types should not be wrapped in data Options =
Options { inferOpt :: Bool
, explainOpt :: Bool
, batchSizeOpt :: Int32 }
deriving ( Generic
, ToSchema GraknSchema "Options"
, FromSchema GraknSchema "Options" ) If that does not work, try making each option into its own data type. data Options =
Options { inferOpt :: InferOpt
, explainOpt :: ExplainOpt
, batchSizeOpt :: BatchSizeOpt }
deriving ( Generic
, ToSchema GraknSchema "Options"
, FromSchema GraknSchema "Options" )
data InferOpt = InferOpt Bool deriving (Generic)
data ExplainOpt = ExplainOpt Bool deriving (Generic)
data BatchSizeOpt = BatchSizeOpt Int32 deriving (Generic) |
the second one did the trick thanks; However, I needed to declare instance Generic Int32 where because GHC told me there is no known instance; if i may: as part of the same protocol, session grpc calls are defined like this: message Session {
enum Type {
DATA = 0;
SCHEMA = 1;
}
message Open {
message Req {
string database = 1;
Type type = 2;
Options options = 3;
}
message Res {
bytes session_id = 1;
}
}
message Close {
message Req {
bytes session_id = 1;
}
message Res {}
}
} How should those nested messages be converted to a data type? i tried just concattenting the message names like `SessionOpenReq" but that obviously didn't work out. |
About About the second problem, I am looking again at the spec to see what that means. I think we do some kind of normalization in which every message goes as a top-level one (right, @kutyel?). But I am not sure how it works when you have several messages with the same name. Could you try to define a single data type for it, and post the error? |
sure;
grakn.proto: // Copyright (C) 2020 Grakn Labs
// GNU Affero GPL notice
syntax = "proto3";
option java_package = "grakn.protocol";
option java_outer_classname = "GraknProto";
import "./database.proto";
import "./session.proto";
import "./transaction.proto";
package grakn.protocol;
service Grakn {
rpc session_open (SessionOpenReq) returns (SessionOpenRes);
} session.proto // Copyright (C) 2020 Grakn Labs
// GNU Affero GPL notice
syntax = "proto3";
option java_package = "grakn.protocol";
option java_outer_classname = "SessionProto";
import "protobuf/options.proto";
package grakn.protocol;
message Session {
enum Type {
DATA = 0;
SCHEMA = 1;
}
message Open {
message Req {
string database = 1;
Type type = 2;
Options options = 3;
}
message Res {
bytes sessionID = 1;
}
}
/*
message Close {
message Req {
bytes sessionID = 1;
}
message Res {}
}
*/
} options.proto // Copyright (C) 2020 Grakn Labs
// GNU Affero GPL notice
syntax = "proto3";
option java_package = "grakn.protocol";
option java_outer_classname = "OptionsProto";
package grakn.protocol;
// TODO: Replace 'oneof' with 'optional' when upgraded to Protobuf 3.13 everywhere
// https://github.com/protocolbuffers/protobuf/issues/1606#issuecomment-618687169
message Options {
oneof inferOpt {
bool infer = 1;
}
oneof explainOpt {
bool explain = 2;
}
oneof batchSizeOpt {
int32 batchSize = 3;
}
} Proto.hs {-# language CPP #-}
{-# language DataKinds #-}
{-# language DeriveAnyClass #-}
{-# language DeriveGeneric #-}
{-# language DerivingStrategies #-}
{-# language DerivingVia #-}
{-# language DuplicateRecordFields #-}
{-# language FlexibleContexts #-}
{-# language FlexibleInstances #-}
{-# language MultiParamTypeClasses #-}
{-# language PolyKinds #-}
{-# language TemplateHaskell #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
module Proto where
import GHC.Generics
import GHC.Int
import Data.Void
import Mu.Quasi.GRpc
import Mu.Quasi.ProtoBuf
import Mu.Schema
import qualified Data.Text as T
import qualified Data.ByteString as BS
import Mu.Adapter.ProtoBuf
grpc "GraknOptionsSchema" (++ "Service") "protobuf/options.proto"
grpc "GraknSessionSchema" (++ "Service") "protobuf/session.proto"
grpc "GraknSchema" (++ "Service") "protobuf/grakn.proto"
instance Generic Int32 where
data Options =
Options { inferOpt :: InferOpt
, explainOpt :: ExplainOpt
, batchSizeOpt :: BatchSizeOpt }
deriving ( Generic
, ToSchema GraknOptionsSchema "Options"
, FromSchema GraknOptionsSchema "Options" )
data InferOpt = InferOpt Bool deriving (Generic)
data ExplainOpt = ExplainOpt Bool deriving (Generic)
data BatchSizeOpt = BatchSizeOpt Int32 deriving (Generic)
data GType = DATA | SCHEMA
deriving ( Generic
, ToSchema GraknSessionSchema "Type"
, FromSchema GraknSessionSchema "Type" )
type TypeFieldMapping = '[ "type_" ':-> "type" ]
{- works until here -}
-- this was just a guess on how it could look like
data SessionOpenReq =
SessionOpenReq { database :: T.Text
, type_ :: GType
, options :: Options }
deriving ( Generic )
deriving ( ToSchema GraknSessionSchema "SessionOpenReq"
, FromSchema GraknSessionSchema "SessionOpenReq" )
via (CustomFieldMapping "SessionOpenReq" TypeFieldMapping SessionOpenReq) build results in
using
grakn protocol is defined here |
I think in avro we do unfold the nested messages to the top level yes, I'm unfamiliar with the protobuff part 😕 |
@faeblDevelopment Does #260 fix the problem for you? Now you should be able to refer to the nested types as |
It definately looks as if it would solve the problem; However, how do I test this?
but it complains there is no .cabal file |
You need to write the following in your
|
thanks; i tried it with the Session.Open.Res and that works perfectly as expected; data SessionOpenRes =
SessionOpenRes { sessionID :: BS.ByteString }
deriving ( Generic
, ToSchema GraknSessionSchema "Session.Open.Res"
, FromSchema GraknSessionSchema "Session.Open.Res" ) this however: type TypeFieldMapping = '[ "type_" ':-> "type" ]
data SessionOpenReq =
SessionOpenReq { database :: T.Text
, type_ :: GType
, options :: Options }
deriving ( Generic )
deriving ( ToSchema GraknSessionSchema "Session.Open.Req"
, FromSchema GraknSessionSchema "Session.Open.Req" )
via (CustomFieldMapping "Session.Open.Req" TypeFieldMapping SessionOpenReq) generates
i verified that it is not the type mapping; could it be connected with |
Unfortunately, as of now you need to have the entire schema in one single file. #257 is related to this. |
I added the however, the error message is still the same (just that the Options message grpc "GraknSessionSchema" (++ "Service") "protobuf/session.proto"
instance Generic Int32 where
data Options =
Options { inferOpt :: InferOpt
, explainOpt :: ExplainOpt
, batchSizeOpt :: BatchSizeOpt }
deriving ( Generic
, ToSchema GraknSessionSchema "Options"
, FromSchema GraknSessionSchema "Options" )
data InferOpt = InferOpt Bool deriving (Generic)
data ExplainOpt = ExplainOpt Bool deriving (Generic)
data BatchSizeOpt = BatchSizeOpt Int32 deriving (Generic)
data GType = DATA | SCHEMA
deriving ( Generic
, ToSchema GraknSessionSchema "Session.Type"
, FromSchema GraknSessionSchema "Session.Type" )
type TypeFieldMapping = '[ "type_" ':-> "type" ]
data SessionOpenReq =
SessionOpenReq { database :: T.Text
, type_ :: GType
, options :: Options }
deriving ( Generic )
deriving ( ToSchema GraknSessionSchema "Session.Open.Req"
, FromSchema GraknSessionSchema "Session.Open.Req" )
via (CustomFieldMapping "Session.Open.Req" TypeFieldMapping SessionOpenReq)
results in
|
Interesting. Could you send over the entire project so I can inspect the current state? |
The solution is to change data SessionOpenReq =
SessionOpenReq { database :: T.Text
, type_ :: Maybe GType
, options :: Maybe Options } This (really tiny) bit of information in the docs point out the reason:
The general rule when translating Protocol Buffers to Mu-Haskell is that anything which is not a primitive type should appear wrapped in |
Thanks very much, I must have skipped over this part of the documentation too fast. great to see that example work 👍 |
tags: grpc, question
I am playing around with the library and came across something I am not capable of handling:
The example protocol I am playing around with has the following message defined:
and i cannot figure out, how to represent the oneof field as the corresponding datatype so that i can derive FromSchema & ToSchema
i tried using a list as above, a
Maybe
, anEither x Void
anEither x ()
; I am running out of ideas how to represent that.I was also unable to find documentation on how to handle
oneof
values;Can you point me to some documentations for this detail or to the right way of handling it?
just on a sidenote if this sounds familiar to anybody: i originally posted this on reddit but got no answers
The text was updated successfully, but these errors were encountered: