pinch-gen 0.4.0.0 → 0.4.1.0
raw patch · 4 files changed
+146/−3 lines, 4 files
Files
- CHANGELOG.md +6/−1
- README.md +137/−0
- pinch-gen.cabal +2/−1
- src/Pinch/Generate.hs +1/−1
CHANGELOG.md view
@@ -1,4 +1,9 @@-0.4 (2021-XX-XX)+0.4.1 (2021-04-26)+==================++* Support for thrift Byte type++0.4 (2021-01-14) ================ * First version. Released on an unsuspecting world.
+ README.md view
@@ -0,0 +1,137 @@++[![build]](https://github.com/phile314/pinch-gen)++`pinch` aims to provide an alternative implementation of Apache Thrift for+Haskell. The `pinch` library itself acts only as a serialization library. Types+specify their Thrift encoding by defining instances of the `Pinchable`+typeclass, which may be done by hand or automatically with the use of Generics.++ [build]: https://github.com/phile314/pinch-gen/workflows/build/badge.svg++Haddock documentation for this package is avilable on [Hackage].++ [Hackage]: http://hackage.haskell.org/package/pinch-gen++Overview+--------++Converts a Thrift file into Haskell code for the pinch library.++Usage:++```+Usage: pinch-gen --in IN_FILE --out OUT_DIR --hashable-vec-mod ARG+ [--no-generate-arbitrary] [--extra-import IMPORT]+ Generate Haskell files from a thrift input file.+```++The `--hashable-vec-mod` argument should be set to a module providing a `Hashable` instance for Vector.+This is required as a Vector may become part of a key of a map, but neither the vector nor the hashable+package provide an instance. For some background, see https://github.com/haskell/vector/pull/102 .The simplest+solution is to depend on the `vector-instances` package and pass `--hashable-vec-mod Data.Vector.Instances` to+pinch-gen.++Compatibility+-------------++| pinch version | pinch-gen version |+|---------------|-------------------|+| 0.4 | 0.4 |+++Example+-------++Let us use this simple Thrift service as an example:++#### **`trivial.thrift`**+```+# A simple struct+struct MyStruct {+ 1: required binary payload;+}++# Trivial exception for testing only.+exception Exception {++ # The exception simply contains a message string.+ 1: required string message;+}++# Trivial service for testing only.+service Trivial {++ # Takes a struct and returns a string.+ string success(1: MyStruct argument);++ # Throws an arbitrary string.+ void failure() throws (1: Exception error);++ # Fire rocket.+ oneway void fireAndForget(1: i32 rocket);+}+```++To generate the corresponding Haskell code we can call pinch-gen:++```+pinch-gen --no-generate-arbitrary --hashable-vec-mod Data.Vector.Instances --in trivial.thrift --out out/+```++This will create the appropriate datatypes for all struct, union and exception types:+++#### **`out/Trivial/Types.hs`**+```+data MyStruct+ = MyStruct+ { myStruct_payload :: Data.ByteString.ByteString+ }+ deriving (Prelude.Eq, GHC.Generics.Generic, Prelude.Show)++data Exception+ = Exception+ { exception_message :: Data.Text.Text+ }+ deriving (Prelude.Eq, GHC.Generics.Generic, Prelude.Show)+```++For the server, a record-style encoding of all functions is used. Given an implementation of these functions,+a `Pinch.Server.ThriftServer` for use with the pinch library can be created:+++#### **`out/Trivial/Server.hs`**+```+data Trivial+ = Trivial+ { success :: (Pinch.Server.Context) -> (MyStruct) -> (Prelude.IO Data.Text.Text)+ , failure :: (Pinch.Server.Context) -> (Prelude.IO ())+ , fireAndForget :: (Pinch.Server.Context) -> (Data.Int.Int32) -> (Prelude.IO ())+ }++trivial_mkServer :: (Trivial) -> Pinch.Server.ThriftServer+trivial_mkServer server = ...+```++For the client, functions creating a `Pinch.Client.ThriftCall` for use with the pinch library are generated.+You can use `Pinch.Client.call` if you want to explicitly match on the success result/thrown exceptions as defined+in the Thrift file. Alternatively, you may use `Pinch.Client.callOrThrow` to directly access the result. In case+the rqeuest failed, `callOrThrow` will throw an exception using `throwIO`.+++#### **`out/Trivial/Client.hs`**+```+success :: (MyStruct) -> (Pinch.Client.ThriftCall Success_Result)+success argument = ...++failure :: (Pinch.Client.ThriftCall Failure_Result)+failure = ...++fireAndForget :: (Data.Int.Int32) -> (Pinch.Client.ThriftCall Pinch.Internal.RPC.Unit)+fireAndForget rocket = ...+```++Caveats+-------++The generated code is currently not formatted very nicely.
pinch-gen.cabal view
@@ -1,7 +1,7 @@ cabal-version: >=1.10 name: pinch-gen-version: 0.4.0.0+version: 0.4.1.0 -- synopsis: synopsis: A code generator for the pinch Thrift library. homepage: https://github.com/phile314/pinch-gen@@ -13,6 +13,7 @@ category: Development build-type: Simple extra-source-files: CHANGELOG.md+ README.md executable pinch-gen main-is: Main.hs
src/Pinch/Generate.hs view
@@ -181,6 +181,7 @@ BinaryType _ _ -> tyCon "Data.ByteString.ByteString" BoolType _ _ -> tyCon "Prelude.Bool" DoubleType _ _ -> tyCon "Prelude.Double"+ ByteType _ _ -> tyCon "Data.Int.Int8" I16Type _ _ -> tyCon "Data.Int.Int16" I32Type _ _ -> tyCon "Data.Int.Int32" I64Type _ _ -> tyCon "Data.Int.Int64"@@ -194,7 +195,6 @@ Nothing -> tyCon $ capitalize ty Just (H.ModuleName n) -> pure $ H.TyCon $ n <> "." <> capitalize (last xs) _ -> tyCon $ capitalize ty- ty -> error $ "Unsupported type: " <> show ty where tyCon = pure . H.TyCon