{-# LANGUAGE OverloadedStrings #-} module Elm.Record (toElmTypeSource,toElmTypeSourceWith) where import Control.Monad.Reader import Elm.Common import Elm.Type import Formatting import Data.Text render :: ElmTypeExpr -> Reader Options Text render (TopLevel (DataType dataTypeName record@(Record _ _))) = sformat ("type alias " % stext % " =\n { " % stext % "\n }") dataTypeName <$> render record render (TopLevel (DataType d s@(Sum _ _))) = sformat ("type " % stext % "\n = " % stext) d <$> render s render (DataType d _) = return d render (Primitive s) = return s render (Sum x y) = sformat (stext % "\n | " % stext) <$> render x <*> render y render (Field t) = render t render (Selector s t) = do fieldModifier <- asks fieldLabelModifier sformat (stext % " : " % stext) (fieldModifier s) <$> render t render (Constructor c Unit) = pure c render (Constructor c t) = sformat (stext % " " % stext) c <$> render t render (Tuple2 x y) = sformat ("( " % stext % ", " % stext % " )") <$> render x <*> render y render (Dict x y) = sformat ("Dict " % stext % " " % stext) <$> render x <*> render y render (Product (Primitive "List") (Primitive "Char")) = return "String" render (Product (Primitive "List") p@(Product _ _)) = sformat ("List (" % stext % ")") <$> render p render (Product (Primitive "List") t) = sformat ("List " % stext) <$> render t render (Product (Primitive "Dict") (Product k v)) = sformat ("Dict " % stext % " " % stext) <$> render k <*> render v render (Product x y) = do bodyX <- render x bodyY <- render y return $ sformat (stext % " " % stext) bodyX (parenthesize y bodyY) render (Record n (Product x y)) = do bodyX <- render (Record n x) bodyY <- render (Record n y) return $ sformat (stext % "\n , " % stext) bodyX bodyY render (Record _ s@(Selector _ _)) = render s render Unit = return "" toElmTypeSourceWith :: ElmType a => Options -> a -> Text toElmTypeSourceWith options x = runReader (render . TopLevel $ toElmType x) options toElmTypeSource :: ElmType a => a -> Text toElmTypeSource = toElmTypeSourceWith defaultOptions