module Elm.Encoder
( toElmEncoderRef
, toElmEncoderRefWith
, toElmEncoderSource
, toElmEncoderSourceWith
) where
import Control.Monad.Reader
import Data.Monoid
import qualified Data.Text as T
import Elm.Common
import Elm.Type
import Text.PrettyPrint.Leijen.Text hiding ((<$>), (<>))
class HasEncoder a where
render :: a -> Reader Options Doc
class HasEncoderRef a where
renderRef :: a -> Reader Options Doc
instance HasEncoder ElmDatatype where
render d@(ElmDatatype name constructor) = do
fnName <- renderRef d
ctor <- render constructor
return $
(fnName <+> ":" <+> stext name <+> "->" <+> "Json.Encode.Value") <$$>
(fnName <+> "x =" <$$> indent 4 ctor)
render (ElmPrimitive primitive) = renderRef primitive
instance HasEncoderRef ElmDatatype where
renderRef (ElmDatatype name _) = pure $ "encode" <> stext name
renderRef (ElmPrimitive primitive) = renderRef primitive
instance HasEncoder ElmConstructor where
render (RecordConstructor _ value) = do
dv <- render value
return . nest 4 $ "Json.Encode.object" <$$> "[" <+> dv <$$> "]"
instance HasEncoder ElmValue where
render (ElmField name value) = do
fieldModifier <- asks fieldLabelModifier
valueBody <- render value
return . spaceparens $
dquotes (stext (fieldModifier name)) <> comma <+>
(valueBody <+> "x." <> stext name)
render (ElmPrimitiveRef primitive) = renderRef primitive
render (ElmRef name) = pure $ "encode" <> stext name
render (Values x y) = do
dx <- render x
dy <- render y
return $ dx <$$> comma <+> dy
instance HasEncoderRef ElmPrimitive where
renderRef EDate = pure $ parens "Json.Encode.string << toString"
renderRef EUnit = pure "Json.Encode.null"
renderRef EInt = pure "Json.Encode.int"
renderRef EChar = pure "Json.Encode.char"
renderRef EBool = pure "Json.Encode.bool"
renderRef EFloat = pure "Json.Encode.float"
renderRef EString = pure "Json.Encode.string"
renderRef (EList (ElmPrimitive EChar)) = pure "Json.Encode.string"
renderRef (EList datatype) = do
dd <- renderRef datatype
return . parens $ "Json.Encode.list << List.map" <+> dd
renderRef (EMaybe datatype) = do
dd <- renderRef datatype
return . parens $ "Maybe.withDefault Json.Encode.null << Maybe.map" <+> dd
renderRef (ETuple2 x y) = do
dx <- renderRef x
dy <- renderRef y
return . parens $ "tuple2" <+> dx <+> dy
renderRef (EDict k v) = do
dk <- renderRef k
dv <- renderRef v
return . parens $ "dict" <+> dk <+> dv
toElmEncoderRefWith
:: ElmType a
=> Options -> a -> T.Text
toElmEncoderRefWith options x =
pprinter $ runReader (renderRef (toElmType x)) options
toElmEncoderRef
:: ElmType a
=> a -> T.Text
toElmEncoderRef = toElmEncoderRefWith defaultOptions
toElmEncoderSourceWith
:: ElmType a
=> Options -> a -> T.Text
toElmEncoderSourceWith options x =
pprinter $ runReader (render (toElmType x)) options
toElmEncoderSource
:: ElmType a
=> a -> T.Text
toElmEncoderSource = toElmEncoderSourceWith defaultOptions