module Elm.Encoder
( toElmEncoderRef
, toElmEncoderRefWith
, toElmEncoderSource
, toElmEncoderSourceWith
) where
import Control.Monad.Reader
import Data.Text
import Elm.Common
import Elm.Type
import Formatting
class HasEncoder a where
render :: a -> Reader Options Text
class HasEncoderRef a where
renderRef :: a -> Reader Options Text
instance HasEncoder ElmDatatype where
render d@(ElmDatatype name constructor) = do
fnName <- renderRef d
sformat
(stext % " : " % stext % " -> Json.Encode.Value" % cr % stext % " x =" % stext)
fnName
name
fnName <$>
render constructor
render (ElmPrimitive primitive) = renderRef primitive
instance HasEncoderRef ElmDatatype where
renderRef (ElmDatatype name _) =
pure $ sformat ("encode" % stext) name
renderRef (ElmPrimitive primitive) =
renderRef primitive
instance HasEncoder ElmConstructor where
render (RecordConstructor _ value) =
sformat (cr % " Json.Encode.object" % cr % " [ " % stext % cr % " ]") <$> render value
instance HasEncoder ElmValue where
render (ElmField name value) = do
fieldModifier <- asks fieldLabelModifier
valueBody <- render value
pure $
sformat
("( \"" % stext % "\", " % stext % " x." % stext % " )")
(fieldModifier name)
valueBody
name
render (ElmPrimitiveRef primitive) = renderRef primitive
render (ElmRef name) = pure $ sformat ("encode" % stext) name
render (Values x y) = sformat (stext % cr % " , " % stext) <$> render x <*> render y
instance HasEncoderRef ElmPrimitive where
renderRef EDate = pure "(Json.Encode.string << toISOString)"
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) = sformat ("(Json.Encode.list << List.map " % stext % ")") <$> renderRef datatype
renderRef (EMaybe datatype) =
sformat ("(Maybe.withDefault Json.Encode.null << Maybe.map " % stext % ")") <$>
renderRef datatype
renderRef (ETuple2 x y) =
sformat ("(tuple2 " % stext % " " % stext % ")") <$> renderRef x <*>
renderRef y
renderRef (EDict k datatype) =
sformat ("(dict " % stext % " " % stext % ")") <$> renderRef k <*> renderRef datatype
toElmEncoderRefWith :: ElmType a => Options -> a -> Text
toElmEncoderRefWith options x = runReader (renderRef (toElmType x)) options
toElmEncoderRef :: ElmType a => a -> Text
toElmEncoderRef = toElmEncoderRefWith defaultOptions
toElmEncoderSourceWith :: ElmType a => Options -> a -> Text
toElmEncoderSourceWith options x = runReader (render (toElmType x)) options
toElmEncoderSource :: ElmType a => a -> Text
toElmEncoderSource = toElmEncoderSourceWith defaultOptions