typed-wire 0.3.0.0 → 0.3.1.0
raw patch · 7 files changed
+65/−55 lines, 7 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ TW.Types: [li_type] :: LibraryInfo -> Text
- TW.Types: LibraryInfo :: Text -> Text -> LibraryInfo
+ TW.Types: LibraryInfo :: Text -> Text -> Text -> LibraryInfo
Files
- README.md +11/−2
- app/Main.hs +29/−29
- src/TW/CodeGen/Elm.hs +17/−17
- src/TW/CodeGen/Haskell.hs +1/−1
- src/TW/CodeGen/PureScript.hs +3/−3
- src/TW/Types.hs +2/−1
- typed-wire.cabal +2/−2
README.md view
@@ -9,8 +9,17 @@ Hackage: [typed-wire](http://hackage.haskell.org/package/typed-wire) Stackage: [typed-wire](https://www.stackage.org/package/typed-wire) -Language idependent type-safe communication+Language independent type-safe communication +## Motivation / WIP Notice++Here are some details on the library:++* I wrote this because I have more and more micro-service architectures. The simplest form is a Haskell (REST-Api) Backend talking with an Elm/Purescript/... frontend. I got really tired of defining all data types in Haskell, Elm, PureScript, ... and writing JSON parsing/serialization functions for them in all languages. typed-wire attempts to solve this/my problem: It generates type definitions and matching JSON parsing/serialization for all target languages from a definition file. It can also generate API definitions, but this feature is not finished yet.+* It's not ready yet - it is still missing some planned features, testing and documentation+* It's used in production at one of my projects to ensure DRY type-safe communication between an Elm client and a Haskell server (www.bahn-buddy.de , german)+* If anyone thinks this is cool, needs it too and would like to help out please shoot me an email :-)+ ## Cli Usage: twirec ```sh@@ -19,7 +28,7 @@ Usage: twirec [--version] [-i|--include-dir DIR] [-e|--entrypoint MODULE-NAME] [--hs-out DIR] [--elm-out DIR] [--purescript-out DIR]- Language idependent type-safe communication+ Language-independent type-safe communication Available options: -h,--help Show this help text
app/Main.hs view
@@ -1,35 +1,35 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskell #-} module Main where import TW.Ast import TW.Check-import TW.Loader-import TW.Parser-import TW.Types import qualified TW.CodeGen.Elm as Elm import qualified TW.CodeGen.Haskell as HS import qualified TW.CodeGen.PureScript as PS+import TW.Loader+import TW.Parser+import TW.Types import qualified Paths_typed_wire as Meta +import Control.Monad (forM_)+import qualified Data.Text as T+import qualified Data.Text.IO as T+import qualified Data.Version as Vers import Development.GitRev import Options.Applicative import System.Directory import System.FilePath-import qualified Data.Text as T-import qualified Data.Text.IO as T-import qualified Data.Traversable as T-import qualified Data.Version as Vers data Options = Options { o_showVersion :: Bool- , o_sourceDirs :: [FilePath]+ , o_sourceDirs :: [FilePath] , o_entryPoints :: [ModuleName]- , o_hsOutDir :: Maybe FilePath- , o_elmOutDir :: Maybe FilePath- , o_psOutDir :: Maybe FilePath+ , o_hsOutDir :: Maybe FilePath+ , o_elmOutDir :: Maybe FilePath+ , o_psOutDir :: Maybe FilePath } optParser :: Parser Options@@ -79,7 +79,7 @@ opts = info (helper <*> optParser) ( fullDesc- <> progDesc "Language idependent type-safe communication"+ <> progDesc "Language-independent type-safe communication" <> header "Generate bindings using typed-wire for different languages" ) @@ -111,22 +111,22 @@ case checkModules ok of Left err -> fail err Right readyModules ->- do _ <- T.forM (o_hsOutDir opts) $ \dir ->- do T.putStrLn $- "Required Haskell library is "- <> li_name HS.libraryInfo <> "@" <> li_version HS.libraryInfo- mapM_ (runner dir HS.makeModule HS.makeFileName) readyModules- _ <- T.forM (o_elmOutDir opts) $ \dir ->- do T.putStrLn $- "Required Elm library is "- <> li_name Elm.libraryInfo <> " version " <> li_version Elm.libraryInfo- mapM_ (runner dir Elm.makeModule Elm.makeFileName) readyModules- _ <- T.forM (o_psOutDir opts) $ \dir ->- do T.putStrLn $- "Required PureScript library is "- <> li_name PS.libraryInfo <> " version " <> li_version PS.libraryInfo- mapM_ (runner dir PS.makeModule PS.makeFileName) readyModules- return ()+ do+ forM_ (o_hsOutDir opts) $ \dir ->+ do printLibraryInfo HS.libraryInfo+ mapM_ (runner dir HS.makeModule HS.makeFileName) readyModules+ forM_ (o_elmOutDir opts) $ \dir ->+ do printLibraryInfo Elm.libraryInfo+ mapM_ (runner dir Elm.makeModule Elm.makeFileName) readyModules+ forM_ (o_psOutDir opts) $ \dir ->+ do printLibraryInfo PS.libraryInfo+ mapM_ (runner dir PS.makeModule PS.makeFileName) readyModules+ return ()++printLibraryInfo :: LibraryInfo -> IO ()+printLibraryInfo li = T.putStrLn $+ "Required " <> li_type li <> " " <>+ li_name li <> " version " <> li_version li runner :: FilePath -> (Module -> T.Text) -> (ModuleName -> FilePath) -> Module -> IO () runner baseDir mkModule mkFilename m =
src/TW/CodeGen/Elm.hs view
@@ -33,7 +33,7 @@ (L.foldl' (</>) "" $ map T.unpack parts) ++ ".elm" libraryInfo :: LibraryInfo-libraryInfo = LibraryInfo "elm-typed-wire-utils" "1.0.0"+libraryInfo = LibraryInfo "Elm" "elm-typed-wire-utils" "2.0.0" makeModule :: Module -> T.Text makeModule m =@@ -43,7 +43,7 @@ , "" , T.intercalate "\n" (map makeImport $ m_imports m) , ""- , "import TypedWire as ELib"+ , "import TypedWire as TW" , "import List as L" , "import Json.Decode as " <> jsonDecQual , "import Json.Decode exposing ((:=))"@@ -185,10 +185,10 @@ | bi == tyInt -> jsonEnc "int" | bi == tyBool -> jsonEnc "bool" | bi == tyFloat -> jsonEnc "float"- | bi == tyBytes -> "ELib.jencAsBase64"- | bi == tyDateTime -> "ELib.jencDateTime"- | bi == tyTime -> "ELib.jencTime"- | bi == tyDate -> "ELib.jencDate"+ | bi == tyBytes -> "TW.encAsBase64"+ | bi == tyDateTime -> "TW.encDateTime"+ | bi == tyTime -> "TW.encTime"+ | bi == tyDate -> "TW.encDate" | bi == tyList -> case tvars of [arg] ->@@ -196,7 +196,7 @@ _ -> error $ "Elm: odly shaped List value" | bi == tyMaybe -> case tvars of- [arg] -> "ELib.encMaybe (" <> jsonEncFor arg <> ")"+ [arg] -> "TW.encMaybe (" <> jsonEncFor arg <> ")" _ -> error $ "Elm: odly shaped Maybe value" | otherwise -> error $ "Elm: Missing jsonEnc for built in type: " ++ show t@@ -217,18 +217,18 @@ | bi == tyInt -> jsonDec "int" | bi == tyBool -> jsonDec "bool" | bi == tyFloat -> jsonDec "float"- | bi == tyBytes -> "ELib.jdecAsBase64"- | bi == tyDateTime -> "ELib.jdecDateTime"- | bi == tyTime -> "ELib.jdecTime"- | bi == tyDate -> "ELib.jdecDate"+ | bi == tyBytes -> "TW.decAsBase64"+ | bi == tyDateTime -> "TW.decDateTime"+ | bi == tyTime -> "TW.decTime"+ | bi == tyDate -> "TW.decDate" | bi == tyList -> case tvars of [arg] -> jsonDec "list" <> " (" <> jsonDecFor arg <> ")"- _ -> error $ "Elm: odly shaped List value"+ _ -> error "Elm: odly shaped List value" | bi == tyMaybe -> case tvars of [arg] -> jsonDec "maybe" <> " (" <> jsonDecFor arg <> ")"- _ -> error $ "Elm: odly shaped Maybe value"+ _ -> error "Elm: odly shaped Maybe value" | otherwise -> error $ "Elm: Missing jsonDec for built in type: " ++ show t @@ -254,12 +254,12 @@ | bi == tyInt -> "Int" | bi == tyBool -> "Bool" | bi == tyFloat -> "Float"- | bi == tyDateTime -> "ELib.DateTime"- | bi == tyTime -> "ELib.Time"- | bi == tyDate -> "ELib.Date"+ | bi == tyDateTime -> "TW.DateTime"+ | bi == tyTime -> "TW.Time"+ | bi == tyDate -> "TW.Date" | bi == tyMaybe -> "(Maybe " <> T.intercalate " " (map makeType tvars) <> ")" | bi == tyList -> "(List " <> T.intercalate " " (map makeType tvars) <> ")"- | bi == tyBytes -> "ELib.AsBase64"+ | bi == tyBytes -> "TW.AsBase64" | otherwise -> error $ "Elm: Unimplemented built in type: " ++ show t
src/TW/CodeGen/Haskell.hs view
@@ -20,7 +20,7 @@ import qualified Data.Text as T libraryInfo :: LibraryInfo-libraryInfo = LibraryInfo "typed-wire-utils" "0.1.0.0"+libraryInfo = LibraryInfo "Haskell" "typed-wire-utils" "0.1.0.0" aesonQual :: T.Text aesonQual = "Data_Aeson_Lib"
src/TW/CodeGen/PureScript.hs view
@@ -19,7 +19,7 @@ import qualified Data.Text as T libraryInfo :: LibraryInfo-libraryInfo = LibraryInfo "purescript-typed-wire" "0.2.0"+libraryInfo = LibraryInfo "Purescript" "purescript-typed-wire" "0.2.0" makeFileName :: ModuleName -> FilePath makeFileName (ModuleName parts) =@@ -153,7 +153,7 @@ , "instance " <> showName (sd_name sd) <> " :: " <> tcPreds (sd_args sd) ["Show"] <> "Show (" <> fullType <> ") where " <> "show (" <> justType <> " a) = " <> T.pack (show justType) <> " ++ \"{\" ++ "- <> T.intercalate " ++ " (map makeFieldShow (sd_fields sd))+ <> T.intercalate " ++ \", \" ++ " (map makeFieldShow (sd_fields sd)) <> " ++ \"}\"" , "instance " <> encoderName (sd_name sd) <> " :: " <> tcPreds (sd_args sd) ["EncodeJson"] <> "EncodeJson" <> " (" <> fullType <> ") where"@@ -232,7 +232,7 @@ let constr = unChoiceName $ ec_name ec in case ec_arg ec of Nothing -> "show (" <> constr <> ") = " <> T.pack (show constr)- Just _ -> "show (" <> constr <> " a) = " <> T.pack (show constr) <> " ++ show a"+ Just _ -> "show (" <> constr <> " a) = " <> T.pack (show constr) <> " ++ \" \" ++ show a" makeChoiceEq ec = let constr = unChoiceName $ ec_name ec in case ec_arg ec of
src/TW/Types.hs view
@@ -4,6 +4,7 @@ data LibraryInfo = LibraryInfo- { li_name :: T.Text+ { li_type :: T.Text+ , li_name :: T.Text , li_version :: T.Text }
typed-wire.cabal view
@@ -1,6 +1,6 @@ name: typed-wire-version: 0.3.0.0-synopsis: Language idependent type-safe communication+version: 0.3.1.0+synopsis: Language-independent type-safe communication description: Please see README.md homepage: http://github.com/typed-wire/typed-wire#readme license: MIT