packages feed

mu-protobuf 0.4.1.0 → 0.4.2.0

raw patch · 4 files changed

+50/−12 lines, 4 filesdep ~mu-schemaPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: mu-schema

API changes (from Hackage documentation)

- Mu.Adapter.ProtoBuf: instance forall typeName fieldName (sch :: Mu.Schema.Definition.Schema typeName fieldName) (name :: typeName) (choices :: [Mu.Schema.Definition.ChoiceDef fieldName]). Mu.Adapter.ProtoBuf.ProtoBridgeEnum sch name choices => Mu.Adapter.ProtoBuf.ProtoBridgeEmbedTerm sch ('Mu.Schema.Definition.DEnum name choices)
+ Mu.Adapter.ProtoBuf: instance forall tn fieldName (sch :: Mu.Schema.Definition.Schema tn fieldName) (ty :: tn) (this :: fieldName) (rest :: [Mu.Schema.Definition.ChoiceDef fieldName]). Mu.Adapter.ProtoBuf.FindZeroEnum_ sch ty ('Mu.Schema.Definition.ChoiceDef this) (Mu.Adapter.ProtoBuf.FindProtoBufId sch ty this) rest => Mu.Adapter.ProtoBuf.FindZeroEnum sch ty ('Mu.Schema.Definition.ChoiceDef this : rest)
+ Mu.Adapter.ProtoBuf: instance forall tn fn (sch :: Mu.Schema.Definition.Schema tn fn) (ty :: tn) (rest :: [Mu.Schema.Definition.ChoiceDef fn]) (this :: Mu.Schema.Definition.ChoiceDef fn) (n :: GHC.Types.Nat). Mu.Adapter.ProtoBuf.FindZeroEnum sch ty rest => Mu.Adapter.ProtoBuf.FindZeroEnum_ sch ty this n rest
+ Mu.Adapter.ProtoBuf: instance forall tn fn (sch :: Mu.Schema.Definition.Schema tn fn) (ty :: tn) (this :: Mu.Schema.Definition.ChoiceDef fn) (rest :: [Mu.Schema.Definition.ChoiceDef fn]). Mu.Adapter.ProtoBuf.FindZeroEnum_ sch ty this 0 rest
+ Mu.Adapter.ProtoBuf: instance forall tn fn (sch :: Mu.Schema.Definition.Schema tn fn) (ty :: tn). (TypeError ...) => Mu.Adapter.ProtoBuf.FindZeroEnum sch ty '[]
+ Mu.Adapter.ProtoBuf: instance forall typeName fieldName (sch :: Mu.Schema.Definition.Schema typeName fieldName) (name :: typeName) (choices :: [Mu.Schema.Definition.ChoiceDef fieldName]). (Mu.Adapter.ProtoBuf.ProtoBridgeEnum sch name choices, Mu.Adapter.ProtoBuf.FindZeroEnum sch name choices) => Mu.Adapter.ProtoBuf.ProtoBridgeEmbedTerm sch ('Mu.Schema.Definition.DEnum name choices)
- Mu.Quasi.ProtoBuf.Example: type Example2ProtoBufSchema = '[ 'DEnum "gender" '[ 'ChoiceDef "male", 'ChoiceDef "female", 'ChoiceDef "nonbinary"], 'DRecord "person" '[ 'FieldDef "names" ('TList ('TPrimitive Text)), 'FieldDef "age" ('TPrimitive Int32), 'FieldDef "gender" ('TOption ('TSchematic "gender"))]]
+ Mu.Quasi.ProtoBuf.Example: type Example2ProtoBufSchema = '[ 'DEnum "gender" '[ 'ChoiceDef "male", 'ChoiceDef "female", 'ChoiceDef "nonbinary"], 'DRecord "person" '[ 'FieldDef "names" ('TList ('TPrimitive Text)), 'FieldDef "age" ('TPrimitive Int32), 'FieldDef "gender" ('TSchematic "gender")]]
- Mu.Quasi.ProtoBuf.Example: type ExampleProtoBufSchema = '[ 'DRecord "person" '[ 'FieldDef "firstName" ('TPrimitive Text), 'FieldDef "lastName" ('TPrimitive Text), 'FieldDef "age" ('TPrimitive Int32), 'FieldDef "gender" ('TOption ('TSchematic "gender")), 'FieldDef "address" ('TOption ('TSchematic "address")), 'FieldDef "lucky_numbers" ('TList ('TPrimitive Int32)), 'FieldDef "things" ('TMap ('TPrimitive Text) ('TPrimitive Int32))], 'DRecord "address" '[ 'FieldDef "postcode" ('TPrimitive Text), 'FieldDef "country" ('TPrimitive Text)], 'DEnum "gender" '[ 'ChoiceDef "nb", 'ChoiceDef "male", 'ChoiceDef "female"]]
+ Mu.Quasi.ProtoBuf.Example: type ExampleProtoBufSchema = '[ 'DRecord "person" '[ 'FieldDef "firstName" ('TPrimitive Text), 'FieldDef "lastName" ('TPrimitive Text), 'FieldDef "age" ('TPrimitive Int32), 'FieldDef "gender" ('TSchematic "gender"), 'FieldDef "address" ('TOption ('TSchematic "address")), 'FieldDef "lucky_numbers" ('TList ('TPrimitive Int32)), 'FieldDef "things" ('TMap ('TPrimitive Text) ('TPrimitive Int32))], 'DRecord "address" '[ 'FieldDef "postcode" ('TPrimitive Text), 'FieldDef "country" ('TPrimitive Text)], 'DEnum "gender" '[ 'ChoiceDef "nb", 'ChoiceDef "male", 'ChoiceDef "female"]]

Files

mu-protobuf.cabal view
@@ -1,5 +1,5 @@ name:          mu-protobuf-version:       0.4.1.0+version:       0.4.2.0 synopsis:   Protocol Buffers serialization and gRPC schema import for Mu microservices 
src/Mu/Adapter/ProtoBuf.hs view
@@ -205,6 +205,7 @@  -- Embedded terms class ProtoBridgeEmbedTerm (sch :: Schema tn fn) (t :: TypeDef tn fn) where+  embedDefaultOneFieldValue :: Maybe (Term sch t)   termToEmbedProto :: FieldNumber -> Term sch t -> PBEnc.MessageBuilder   embedProtoToOneFieldValue :: PBDec.Parser PBDec.RawPrimitive (Term sch t)   -- support for packed encodings@@ -257,6 +258,7 @@  instance ProtoBridgeTerm sch ('DRecord name args)          => ProtoBridgeEmbedTerm sch ('DRecord name args) where+  embedDefaultOneFieldValue = Nothing   termToEmbedProto fid v = PBEnc.embedded fid (termToProto v)   embedProtoToOneFieldValue = PBDec.embedded' (protoToTerm @_ @_ @sch @('DRecord name args))   supportsPackingTerm _ = False@@ -271,8 +273,10 @@   termToProto = error "protobuf requires wrapping enums in a message"   protoToTerm = error "protobuf requires wrapping enums in a message" -instance ProtoBridgeEnum sch name choices+instance ( ProtoBridgeEnum sch name choices+         , FindZeroEnum sch name choices )          => ProtoBridgeEmbedTerm sch ('DEnum name choices) where+  embedDefaultOneFieldValue = Just $ TEnum $ findZeroEnum @_ @_ @sch @name @choices   termToEmbedProto fid (TEnum v) = PBEnc.int32 fid (enumToProto @_ @_ @sch @name v)   embedProtoToOneFieldValue = PBDec.int32 >>= fmap TEnum . protoToEnum @_ @_ @sch @name   supportsPackingTerm _ = True@@ -296,6 +300,27 @@     | otherwise      = S <$> protoToEnum @_ @_ @sch @ty n     where enumValue = fromIntegral (natVal (Proxy @(FindProtoBufId sch ty c))) +class FindZeroEnum (sch :: Schema tn fn) (ty :: tn) (choices :: [ChoiceDef fn]) where+  findZeroEnum :: NS Proxy choices+class FindZeroEnum_ (sch :: Schema tn fn) (ty :: tn) (thisChoice :: ChoiceDef fn) (pbId :: Nat) (restOfChoices :: [ChoiceDef fn]) where+  findZeroEnum_ :: NS Proxy (thisChoice ': restOfChoices)++instance TypeError ('Text "could not find value 0 for enum")+         => FindZeroEnum sch ty '[] where+  findZeroEnum = error "this should never be called"+instance (FindZeroEnum_ sch ty ('ChoiceDef this) (FindProtoBufId sch ty this) rest)+         => FindZeroEnum sch ty ('ChoiceDef this ': rest) where+  findZeroEnum+    = findZeroEnum_ @_ @_ @sch @ty @('ChoiceDef this) @(FindProtoBufId sch ty this) @rest++instance {-# OVERLAPPABLE #-}+         (FindZeroEnum sch ty rest)+         => FindZeroEnum_ sch ty this n rest where+  findZeroEnum_ = S (findZeroEnum @_ @_ @sch @ty @rest)+instance {-# OVERLAPS #-}+         FindZeroEnum_ sch ty this 0 rest where+  findZeroEnum_ = Z Proxy+ -- SIMPLE -- ------ @@ -409,7 +434,7 @@  instance ProtoBridgeEmbedTerm sch (sch :/: t)          => ProtoBridgeOneFieldValue sch ('TSchematic t) where-  defaultOneFieldValue = Nothing+  defaultOneFieldValue = FSchematic <$> embedDefaultOneFieldValue   oneFieldValueToProto fid (FSchematic v) = termToEmbedProto fid v   protoToOneFieldValue = FSchematic <$> embedProtoToOneFieldValue   supportsPacking _ = supportsPackingTerm (Proxy @(Term sch (sch :/: t)))
src/Mu/Quasi/ProtoBuf.hs view
@@ -65,8 +65,17 @@ schemaFromProtoBuf :: P.ProtoBuf -> Q (Type, Type) schemaFromProtoBuf P.ProtoBuf {P.types = tys} = do   let decls = flattenDecls (("", tys) :| []) tys-  (schTys, anns) <- unzip <$> mapM pbTypeDeclToType decls+  (schTys, anns) <- unzip <$> mapM (pbTypeDeclToType $ shouldOptional decls) decls   pure (typesToList schTys, typesToList (concat anns))+  where+    shouldOptional :: [P.TypeDeclaration] -> P.TypeName -> Bool+    shouldOptional [] _ = error "this should never happen"+    shouldOptional (P.DMessage nm _ _ _ _ : _) this+      | nm == last this = True+    shouldOptional (P.DEnum nm _ _ : _) this+      | nm == last this = False+    shouldOptional (_ : rest) this+      = shouldOptional rest this  flattenDecls :: NonEmpty (P.Identifier, [P.TypeDeclaration]) -> [P.TypeDeclaration] -> [P.TypeDeclaration] flattenDecls (currentScope :| higherScopes) = concatMap flattenDecl@@ -113,8 +122,8 @@         "" -> x         _  -> fst currentScope <> "." <> x -pbTypeDeclToType :: P.TypeDeclaration -> Q (Type, [Type])-pbTypeDeclToType (P.DEnum name _ fields) = do+pbTypeDeclToType :: (P.TypeName -> Bool) -> P.TypeDeclaration -> Q (Type, [Type])+pbTypeDeclToType _ (P.DEnum name _ fields) = do   (tys, anns) <- unzip <$> mapM pbChoiceToType fields   (,) <$> [t|'DEnum $(textToStrLit name) $(pure $ typesToList tys)|] <*> pure anns   where@@ -122,7 +131,7 @@     pbChoiceToType (P.EnumField nm number _)       = (,) <$> [t|'ChoiceDef $(textToStrLit nm) |]             <*> [t|'AnnField $(textToStrLit name) $(textToStrLit nm) ('ProtoBufId $(intToLit number) '[]) |]-pbTypeDeclToType (P.DMessage name _ _ fields _) = do+pbTypeDeclToType shouldOptional (P.DMessage name _ _ fields _) = do   (tys, anns) <- unzip <$> mapM pbMsgFieldToType fields   (,) <$> [t|'DRecord $(textToStrLit name) $(pure $ typesToList tys)|] <*> pure anns   where@@ -131,8 +140,12 @@     -- it's possible to distinguish whether it's missing on wire     -- or should be set to the default, so use Option     -- +info -> https://github.com/higherkindness/mu-haskell/pull/130#issuecomment-596433307-    pbMsgFieldToType (P.NormalField P.Single ty@(P.TOther _) nm n opts) =+    pbMsgFieldToType (P.NormalField P.Single ty@(P.TOther innerTy) nm n opts)+        | shouldOptional innerTy =         (,) <$> [t| 'FieldDef $(textToStrLit nm) ('TOption $(pbFieldTypeToType ty)) |]+            <*> [t| 'AnnField $(textToStrLit name) $(textToStrLit nm) ('ProtoBufId $(intToLit n) $(typesToList <$> mapM pbOption opts)) |]+        | otherwise =+        (,) <$> [t| 'FieldDef $(textToStrLit nm) $(pbFieldTypeToType ty) |]             <*> [t| 'AnnField $(textToStrLit name) $(textToStrLit nm) ('ProtoBufId $(intToLit n) $(typesToList <$> mapM pbOption opts)) |]     pbMsgFieldToType (P.NormalField P.Single ty nm n opts) =         (,) <$> [t| 'FieldDef $(textToStrLit nm) $(pbFieldTypeToType ty) |]
test/ProtoBuf.hs view
@@ -25,7 +25,7 @@   = MPerson { firstName     :: T.Text             , lastName      :: T.Text             , age           :: Maybe Int-            , gender        :: Maybe Gender+            , gender        :: Gender             , address       :: MAddress             , lucky_numbers :: [Int]             , things        :: M.Map T.Text Int }@@ -54,7 +54,7 @@      , 'AnnField "gender" "gender7" ('ProtoBufId 11 '[])      , 'AnnField "gender" "gender8" ('ProtoBufId 12 '[])      , 'AnnField "gender" "gender9" ('ProtoBufId 13 '[])-     , 'AnnField "gender" "unspecified" ('ProtoBufId 14 '[])+     , 'AnnField "gender" "unspecified" ('ProtoBufId 0 '[])      , 'AnnField "address" "postcode" ('ProtoBufId 1 '[])      , 'AnnField "address" "country"  ('ProtoBufId 2 '[])      , 'AnnField "person" "firstName" ('ProtoBufId 1 '[])@@ -70,11 +70,11 @@  examplePerson1, examplePerson2 :: MPerson examplePerson1 = MPerson "Haskellio" "Gómez"-                         (Just 30) (Just Male)+                         (Just 30) Male                          exampleAddress [1,2,3]                          (M.fromList [("pepe", 1), ("juan", 2)]) examplePerson2 = MPerson "Cuarenta" "Siete"-                         Nothing Nothing+                         Nothing Unspecified                          exampleAddress [] M.empty  main :: IO ()