module Elm ( ToElm (..) , Options (..) , Expr (..) , Primitive (..) , Generator (..) , defaultOptions , genericToElm , generateElm ) where import Data.List import Data.List.Split import Elm.Decoder import Elm.Encoder import Elm.Helpers import Elm.Record import Elm.Types import System.Directory import System.FilePath imports :: [(Expr, [Generator])] -> [String] imports inclusions = map toImport $ ti ++ di ++ ei where generators = concat $ map snd inclusions ti = if Type `elem` generators then [ ("Date", Just "Date") ] else [] di = if Decoder `elem` generators || ListDecoder `elem` generators then [ ("Json.Decode", Just "(:=)") , ("Json.Decode.Extra", Just "(|:)") ] else [] ei = if Encoder `elem` generators then [ ("Json.Encode", Nothing) , ("Date.Format", Nothing) ] else [] toImport (moduleName, Nothing) = "import " ++ moduleName toImport (moduleName, Just exp) = "import " ++ moduleName ++ " exposing (" ++ exp ++ ")" generate :: Generator -> Expr -> String generate Type = record generate Decoder = decoder generate ListDecoder = listDecoder generate Encoder = encoder generateElm :: FilePath -> String -> [String] -> [(Expr, [Generator])] -> IO () generateElm destination moduleName customImports inclusions = do createDirectoryIfMissing True directory writeFile filePath fileBody putStrLn $ "Generated: " ++ filePath where namespace = "module " ++ moduleName ++ " exposing (..)" extraImports = map (\i -> "import " ++ i ++ " exposing (..)") customImports allImports = format $ imports inclusions ++ extraImports definitions = map (\(e, gs) -> format $ pad $ map (flip generate e) gs) inclusions pad = intersperse "\n" fileBody = format $ pad $ filter (not . null) $ namespace : allImports : definitions filePath = intercalate "/" (filter (not . null) $ destination : splitOn "." moduleName) ++ ".elm" directory = takeDirectory filePath