-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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: