@@ -1,4 +1,3 @@
2{-# LANGUAGE RecordWildCards #-}
1{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
@@ -20,11 +19,8 @@ import Elm.Json (jsonParserForType, jsonSerForType)
20import qualified Elm.Module as Elm
19import qualified Elm.Module as Elm
21import Elm.TyRep (ETCon(..), EType(..), ETypeDef(..), toElmType)
20import Elm.TyRep (ETCon(..), EType(..), ETypeDef(..), toElmType)
22import Elm.TyRender (renderElm)
21import Elm.TyRender (renderElm)
23−#if MIN_VERSION_elm_bridge(0,6,0)
24−import Elm.Versions (ElmVersion(Elm0p19))
26import Elm.Versions (ElmVersion(Elm0p18))
22import Elm.Versions (ElmVersion(Elm0p18))
28import Servant.Elm.Internal.Foreign (LangElm, getEndpoints)
24import Servant.Elm.Internal.Foreign (LangElm, getEndpoints)
29import qualified Servant.Foreign as F
25import qualified Servant.Foreign as F
30import System.Directory (createDirectoryIfMissing)
26import System.Directory (createDirectoryIfMissing)
@@ -53,22 +49,16 @@ data ElmOptions = ElmOptions
55 urlPrefix :: UrlPrefix
51 urlPrefix :: UrlPrefix
56− , elmTypeAlterations :: (EType -> EType)
52+ , elmTypeAlterations :: (EType -> EType)
57 -- ^ Alterations to perform on ETypes before code generation.
53 -- ^ Alterations to perform on ETypes before code generation.
58 , elmAlterations :: (ETypeDef -> ETypeDef)
54 , elmAlterations :: (ETypeDef -> ETypeDef)
59 -- ^ Alterations to perform on ETypeDefs before code generation.
55 -- ^ Alterations to perform on ETypeDefs before code generation.
60− , elmToString :: (EType -> Text)
56+ , elmToString :: (EType -> Text)
61 -- ^ Elm functions creating a string from a given type.
57 -- ^ Elm functions creating a string from a given type.
62 , emptyResponseElmTypes :: [EType]
58 , emptyResponseElmTypes :: [EType]
63 -- ^ Types that represent an empty Http response.
59 -- ^ Types that represent an empty Http response.
64 , stringElmTypes :: [EType]
60 , stringElmTypes :: [EType]
65 -- ^ Types that represent a String.
61 -- ^ Types that represent a String.
66− , expectJsonMethod :: Text
67− -- ^ The function to use for JSON responses.
68− , expectStringMethod :: Text
69− -- ^ The function to use for string responses.
70− , httpErrorType :: Text
71− -- ^ The type to use for Http errors.
@@ -92,9 +82,6 @@ The default options are:
92> , stringElmTypes =
82> , stringElmTypes =
93> [ getType (Proxy :: Proxy String)
83> [ getType (Proxy :: Proxy String)
94> , getType (Proxy :: Proxy T.Text) ]
84> , getType (Proxy :: Proxy T.Text) ]
95−> , expectJsonMethod = "Http.expectJson"
96−> , expectStringMethod = "Http.expectString"
97−> , httpErrorType = "Http.Error"
100defElmOptions :: ElmOptions
87defElmOptions :: ElmOptions
@@ -110,9 +97,6 @@ defElmOptions = ElmOptions
110 [ toElmType (Proxy :: Proxy String)
97 [ toElmType (Proxy :: Proxy String)
111 , toElmType (Proxy :: Proxy T.Text)
98 , toElmType (Proxy :: Proxy T.Text)
113− , expectJsonMethod = "Http.expectJson"
114− , expectStringMethod = "Http.expectString"
115− , httpErrorType = "Http.Error"
@@ -131,7 +115,6 @@ The default required imports are:
131> import Set
115> import Set
132> import Http
116> import Http
133> import String
117> import String
135> import Url.Builder
118> import Url.Builder
137defElmImports :: Text
120defElmImports :: Text
@@ -145,7 +128,6 @@ defElmImports =
145 , "import Set"
128 , "import Set"
146 , "import Http"
129 , "import Http"
147 , "import String"
130 , "import String"
149 , "import Url.Builder"
131 , "import Url.Builder"
@@ -167,12 +149,7 @@ generateElmModuleWith ::
167generateElmModuleWith options namespace imports rootDir typeDefs api = do
149generateElmModuleWith options namespace imports rootDir typeDefs api = do
168 let out =
150 let out =
169 T.unlines $
151 T.unlines $
171−#if MIN_VERSION_elm_bridge(0,6,0)
172− T.pack $ Elm.moduleHeader Elm0p19 moduleName
174− T.pack $ Elm.moduleHeader Elm0p18 moduleName
152+ [ T.pack $ Elm.moduleHeader Elm0p18 moduleName
177 , imports
154 , imports
178 , T.pack $ Elm.makeModuleContentWithAlterations (elmAlterations options) typeDefs
155 , T.pack $ Elm.makeModuleContentWithAlterations (elmAlterations options) typeDefs
@@ -259,7 +236,7 @@ generateElmForRequest opts request =
260 request ^. F.reqFuncName . to (replace . F.camelCase) . to stext
237 request ^. F.reqFuncName . to (replace . F.camelCase) . to stext
262− replace = T.replace "-" "" . T.replace "." "" . T.replace " " ""
239+ replace = T.replace "-" "" . T.replace "." ""
264 typeSignature =
241 typeSignature =
265 mkTypeSignature opts request
242 mkTypeSignature opts request
@@ -321,7 +298,7 @@ mkTypeSignature opts request =
321 toMsgType :: Maybe Doc
298 toMsgType :: Maybe Doc
322 toMsgType = do
299 toMsgType = do
323 result <- fmap elmTypeRef $ request ^. F.reqReturnType
300 result <- fmap elmTypeRef $ request ^. F.reqReturnType
324− Just ("(Result" <+> stext (httpErrorType opts) <+> parens result <+> "-> msg)")
301+ Just ("(Result Http.Error " <+> parens result <+> " -> msg)")
326 returnType :: Maybe Doc
303 returnType :: Maybe Doc
327 returnType = do
304 returnType = do
@@ -339,7 +316,7 @@ elmCaptureArg segment =
339 "capture_" <>
316 "capture_" <>
340 F.captureArg segment ^. F.argName . to (stext . replace . F.unPathSegment)
317 F.captureArg segment ^. F.argName . to (stext . replace . F.unPathSegment)
342− replace = T.replace "-" "_" . T.replace " " "_"
319+ replace = T.replace "-" "_"
345elmQueryArg :: F.QueryArg EType -> Doc
322elmQueryArg :: F.QueryArg EType -> Doc
@@ -443,7 +420,7 @@ mkLetParams opts request =
448 elmName = elmQueryArg qarg
425 elmName = elmQueryArg qarg
449 name = qarg ^. F.queryArgName . F.argName . to (stext . F.unPathSegment)
426 name = qarg ^. F.queryArgName . F.argName . to (stext . F.unPathSegment)
@@ -510,14 +487,14 @@ mkRequest opts request =
511 case request ^. F.reqReturnType of
488 case request ^. F.reqReturnType of
512 Just elmTypeExpr
489 Just elmTypeExpr
513− | isEmptyType opts $ (elmTypeAlterations opts) elmTypeExpr
490+ | isEmptyType opts elmTypeExpr
514 -- let elmConstructor = T.pack (renderElm elmTypeExpr)
491 -- let elmConstructor = T.pack (renderElm elmTypeExpr)
516− stext (expectStringMethod opts) <> line <+> indent i "(\\x -> case x of" <> line <+>
493+ "Http.expectString " <> line <+> indent i "(\\x -> case x of" <> line <+>
517 indent i "Err e -> toMsg (Err e)" <> line <+>
494 indent i "Err e -> toMsg (Err e)" <> line <+>
518 indent i "Ok _ -> toMsg (Ok ()))"
495 indent i "Ok _ -> toMsg (Ok ()))"
519 Just elmTypeExpr ->
496 Just elmTypeExpr ->
520− stext (expectJsonMethod opts) <+> "toMsg" <+> renderDecoderName ((elmTypeAlterations opts) elmTypeExpr)
497+ "Http.expectJson toMsg" <+> renderDecoderName elmTypeExpr
521 Nothing -> error "mkHttpRequest: no reqReturnType?"
498 Nothing -> error "mkHttpRequest: no reqReturnType?"
522 -- case request ^. F.reqReturnType of
499 -- case request ^. F.reqReturnType of
523 -- Just elmTypeExpr | isEmptyType opts elmTypeExpr ->
500 -- Just elmTypeExpr | isEmptyType opts elmTypeExpr ->
@@ -545,8 +522,6 @@ renderDecoderName elmTypeExpr =
545 parens ("Json.Decode.list " <> parens (renderDecoderName t))
522 parens ("Json.Decode.list " <> parens (renderDecoderName t))
546 ETyApp (ETyCon (ETCon "Maybe")) t ->
523 ETyApp (ETyCon (ETCon "Maybe")) t ->
547 parens ("Json.Decode.maybe " <> parens (renderDecoderName t))
524 parens ("Json.Decode.maybe " <> parens (renderDecoderName t))
549− parens (renderDecoderName x <+> renderDecoderName y)
550 ETyCon (ETCon "Int") -> "Json.Decode.int"
525 ETyCon (ETCon "Int") -> "Json.Decode.int"
551 ETyCon (ETCon "String") -> "Json.Decode.string"
526 ETyCon (ETCon "String") -> "Json.Decode.string"
552 _ -> ("jsonDec" <> stext (T.pack (renderElm elmTypeExpr)))
527 _ -> ("jsonDec" <> stext (T.pack (renderElm elmTypeExpr)))
@@ -564,7 +539,7 @@ mkUrl opts segments =
565 urlBuilder :: Doc
540 urlBuilder :: Doc
566 urlBuilder = case urlPrefix opts of
541 urlBuilder = case urlPrefix opts of
567− Dynamic -> "Url.Builder.crossOrigin urlBase" :: Doc
542+ Dynamic -> "Url.Builder.absolute" :: Doc
568 Static url -> "Url.Builder.crossOrigin" <+> dquotes (stext url)
543 Static url -> "Url.Builder.crossOrigin" <+> dquotes (stext url)
570 segmentToDoc :: F.Segment EType -> Doc
545 segmentToDoc :: F.Segment EType -> Doc
@@ -574,10 +549,10 @@ mkUrl opts segments =
574 dquotes (stext (F.unPathSegment path))
549 dquotes (stext (F.unPathSegment path))
575 F.Cap arg ->
550 F.Cap arg ->
577− toStringSrc =
552+ toStringSrc =
578− toString opts (elmTypeAlterations opts (maybeOf (arg ^. F.argType)))
553+ toString opts (maybeOf (arg ^. F.argType))
580− "Url.percentEncode " <> pipeRight [elmCaptureArg s, toStringSrc]
555+ pipeRight [elmCaptureArg s, toStringSrc]
583mkQueryParams
558mkQueryParams
@@ -595,7 +570,7 @@ response body.
596isEmptyType :: ElmOptions -> EType -> Bool
571isEmptyType :: ElmOptions -> EType -> Bool
597isEmptyType opts elmTypeExpr =
572isEmptyType opts elmTypeExpr =
598− (elmTypeAlterations opts elmTypeExpr) `elem` emptyResponseElmTypes opts
573+ elmTypeExpr `elem` emptyResponseElmTypes opts
601{- | Determines whether we call `toString` on URL captures and query params of
576{- | Determines whether we call `toString` on URL captures and query params of
@@ -603,7 +578,7 @@ this type in Elm.
604isElmStringType :: ElmOptions -> EType -> Bool
579isElmStringType :: ElmOptions -> EType -> Bool
605isElmStringType opts elmTypeExpr =
580isElmStringType opts elmTypeExpr =
606− (elmTypeAlterations opts elmTypeExpr) `elem` stringElmTypes opts
581+ elmTypeExpr `elem` stringElmTypes opts
608{- | Determines whether a type is 'Maybe a' where 'a' is something akin to a 'String'.
583{- | Determines whether a type is 'Maybe a' where 'a' is something akin to a 'String'.
@@ -645,7 +620,7 @@ elmListOfMaybes ds = "List.filterMap identity" <$> indent 4 (elmList ds)
645defaultElmToString :: EType -> Text
620defaultElmToString :: EType -> Text
646defaultElmToString argType =
621defaultElmToString argType =
647 case argType of
622 case argType of
648− ETyCon (ETCon "Bool") -> "(\\value -> if value then \"true\" else \"false\")"
623+ ETyCon (ETCon "Bool") -> "(\\value -> if value then \"1\" else \"0\")"
649 ETyCon (ETCon "Float") -> "String.fromFloat"
624 ETyCon (ETCon "Float") -> "String.fromFloat"
650 ETyCon (ETCon "Char") -> "String.fromChar"
625 ETyCon (ETCon "Char") -> "String.fromChar"
651 ETyApp (ETyCon (ETCon "Maybe")) v -> "(Maybe.map " <> defaultElmToString v <> " >> Maybe.withDefault \"\")"
626 ETyApp (ETyCon (ETCon "Maybe")) v -> "(Maybe.map " <> defaultElmToString v <> " >> Maybe.withDefault \"\")"