{-# LANGUAGE OverloadedStrings #-} 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