module Elm.Decoder
( toElmDecoderRef
, toElmDecoderRefWith
, toElmDecoderSource
, toElmDecoderSourceWith
) where
import Control.Monad.Reader
import Data.Text
import Elm.Common
import Elm.Type
import Formatting
class HasDecoder a where
render :: a -> Reader Options Text
class HasDecoderRef a where
renderRef :: a -> Reader Options Text
instance HasDecoder ElmDatatype where
render d@(ElmDatatype name constructor) = do
fnName <- renderRef d
sformat
(stext % " : Decoder " % stext % cr % stext % " =" % cr % stext)
fnName
name
fnName <$>
render constructor
render (ElmPrimitive primitive) = renderRef primitive
instance HasDecoderRef ElmDatatype where
renderRef (ElmDatatype name _) =
pure $ sformat ("decode" % stext) name
renderRef (ElmPrimitive primitive) =
renderRef primitive
instance HasDecoder ElmConstructor where
render (NamedConstructor name value) =
sformat (" decode " % stext % cr % stext) name <$> render value
render (RecordConstructor name value) =
sformat (" decode " % stext % cr % stext) name <$> render value
instance HasDecoder ElmValue where
render (ElmRef name) = pure (sformat ("decode" % stext) name)
render (ElmPrimitiveRef primitive) = renderRef primitive
render (Values x y) = sformat (stext % cr % stext) <$> render x <*> render y
render (ElmField name value) = do
fieldModifier <- asks fieldLabelModifier
sformat
(" |> required \"" % stext % "\" " % stext)
(fieldModifier name) <$>
render value
instance HasDecoderRef ElmPrimitive where
renderRef (EList (ElmPrimitive EChar)) = pure "string"
renderRef (EList datatype) =
sformat ("(list " % stext % ")") <$> renderRef datatype
renderRef (EDict key value) =
sformat ("(map Dict.fromList " % stext % ")") <$>
renderRef (EList (ElmPrimitive (ETuple2 (ElmPrimitive key) value)))
renderRef (EMaybe datatype) =
sformat ("(maybe " % stext % ")") <$> renderRef datatype
renderRef (ETuple2 x y) =
sformat ("(tuple2 (,) " % stext % " " % stext % ")") <$> renderRef x <*>
renderRef y
renderRef EUnit = pure "(succeed ())"
renderRef EDate = pure "(customDecoder string Date.fromString)"
renderRef EInt = pure "int"
renderRef EBool = pure "bool"
renderRef EChar = pure "char"
renderRef EFloat = pure "float"
renderRef EString = pure "string"
toElmDecoderRefWith :: ElmType a => Options -> a -> Text
toElmDecoderRefWith options x = runReader (renderRef (toElmType x)) options
toElmDecoderRef :: ElmType a => a -> Text
toElmDecoderRef = toElmDecoderRefWith defaultOptions
toElmDecoderSourceWith :: ElmType a => Options -> a -> Text
toElmDecoderSourceWith options x = runReader (render (toElmType x)) options
toElmDecoderSource :: ElmType a => a -> Text
toElmDecoderSource = toElmDecoderSourceWith defaultOptions