module Elm.Record
( toElmTypeRef
, toElmTypeRefWith
, toElmTypeSource
, toElmTypeSourceWith
) where
import Control.Monad.Reader
import Data.Text
import Elm.Common
import Elm.Type
import Formatting
class HasType a where
render :: a -> Reader Options Text
class HasTypeRef a where
renderRef :: a -> Reader Options Text
instance HasType ElmDatatype where
render d@(ElmDatatype _ constructor@(RecordConstructor _ _)) =
sformat ("type alias " % stext % " =" % cr % stext) <$> renderRef d <*> render constructor
render d@(ElmDatatype _ constructor@(MultipleConstructors _)) =
sformat ("type " % stext % cr % " = " % stext) <$> renderRef d <*> render constructor
render d@(ElmDatatype _ constructor@(NamedConstructor _ _)) =
sformat ("type " % stext % cr % " = " % stext) <$> renderRef d <*> render constructor
render (ElmPrimitive primitive) = renderRef primitive
instance HasTypeRef ElmDatatype where
renderRef (ElmDatatype typeName _) =
pure typeName
renderRef (ElmPrimitive primitive) =
renderRef primitive
instance HasType ElmConstructor where
render (RecordConstructor _ value) =
sformat (" { " % stext % cr % " }") <$> render value
render (NamedConstructor constructorName value) =
sformat (stext % stext) constructorName <$> render value
render (MultipleConstructors constructors) =
fmap (Data.Text.intercalate "\n | ") . sequence $ render <$> constructors
instance HasType ElmValue where
render (ElmRef name) = pure name
render ElmEmpty = pure ""
render (Values x y) =
sformat (stext % cr % " , " % stext) <$> render x <*> render y
render (ElmPrimitiveRef primitive) = sformat (" " % stext) <$> renderRef primitive
render (ElmField name value) = do
fieldModifier <- asks fieldLabelModifier
sformat (stext % " :" % stext) (fieldModifier name) <$> render value
instance HasTypeRef ElmPrimitive where
renderRef (EList (ElmPrimitive EChar)) = renderRef EString
renderRef (EList datatype) = sformat ("List (" % stext % ")") <$> renderRef datatype
renderRef (ETuple2 x y) =
sformat ("( " % stext % ", " % stext % " )") <$> renderRef x <*> renderRef y
renderRef (EMaybe datatype) =
sformat ("Maybe (" % stext % ")") <$> renderRef datatype
renderRef (EDict k v) =
sformat ("Dict (" % stext % ") (" % stext % ")") <$> renderRef k <*> renderRef v
renderRef EInt = pure "Int"
renderRef EDate = pure "Date"
renderRef EBool = pure "Bool"
renderRef EChar = pure "Char"
renderRef EString = pure "String"
renderRef EUnit = pure "()"
renderRef EFloat = pure "Float"
toElmTypeRefWith :: ElmType a => Options -> a -> Text
toElmTypeRefWith options x = runReader (renderRef (toElmType x)) options
toElmTypeRef :: ElmType a => a -> Text
toElmTypeRef = toElmTypeRefWith defaultOptions
toElmTypeSourceWith :: ElmType a => Options -> a -> Text
toElmTypeSourceWith options x = runReader (render (toElmType x)) options
toElmTypeSource :: ElmType a => a -> Text
toElmTypeSource = toElmTypeSourceWith defaultOptions