module Language.Haskell.Format
  ( autoSettings
  , format
  , formatters
  , hlint
  , hindent
  , stylish
  , Settings
  , Formatter(..)
  , Suggestion(..)
  , HaskellSource(..)
  , Reformatted(..)
  ) where

import qualified Language.Haskell.Format.HIndent as HIndent
import qualified Language.Haskell.Format.HLint   as HLint
import qualified Language.Haskell.Format.Stylish as Stylish
import           Language.Haskell.Format.Types

data Settings =
  Settings

autoSettings :: IO Settings
autoSettings :: IO Settings
autoSettings = Settings -> IO Settings
forall (m :: * -> *) a. Monad m => a -> m a
return Settings
Settings

hlint :: Settings -> IO Formatter
hlint :: Settings -> IO Formatter
hlint Settings
_ = (ParseFlags, [Classify], Hint) -> Formatter
HLint.suggester ((ParseFlags, [Classify], Hint) -> Formatter)
-> IO (ParseFlags, [Classify], Hint) -> IO Formatter
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (ParseFlags, [Classify], Hint)
HLint.autoSettings

hindent :: Settings -> IO Formatter
hindent :: Settings -> IO Formatter
hindent Settings
_ = Settings -> Formatter
HIndent.formatter (Settings -> Formatter) -> IO Settings -> IO Formatter
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Settings
HIndent.autoSettings

stylish :: Settings -> IO Formatter
stylish :: Settings -> IO Formatter
stylish Settings
_ = Settings -> Formatter
Stylish.formatter (Settings -> Formatter) -> IO Settings -> IO Formatter
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Settings
Stylish.autoSettings

errorFor :: String -> Formatter -> Formatter
errorFor :: String -> Formatter -> Formatter
errorFor String
name (Formatter HaskellSource -> Either String Reformatted
formatter) =
  (HaskellSource -> Either String Reformatted) -> Formatter
Formatter ((HaskellSource -> Either String Reformatted) -> Formatter)
-> (HaskellSource -> Either String Reformatted) -> Formatter
forall a b. (a -> b) -> a -> b
$ \HaskellSource
source -> Either String Reformatted -> Either String Reformatted
forall b. Either String b -> Either String b
prefixName (HaskellSource -> Either String Reformatted
formatter HaskellSource
source)
  where
    prefixName :: Either String b -> Either String b
prefixName (Left String
err) = String -> Either String b
forall a b. a -> Either a b
Left (String
"Error in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
err)
    prefixName (Right b
a)  = b -> Either String b
forall a b. b -> Either a b
Right b
a

formatters :: Settings -> IO [Formatter]
formatters :: Settings -> IO [Formatter]
formatters Settings
s = ((String, Settings -> IO Formatter) -> IO Formatter)
-> [(String, Settings -> IO Formatter)] -> IO [Formatter]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (\(String
name, Settings -> IO Formatter
f) -> (Formatter -> Formatter) -> IO Formatter -> IO Formatter
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Formatter -> Formatter
errorFor String
name) (Settings -> IO Formatter
f Settings
s)) [(String, Settings -> IO Formatter)]
named
  where
    named :: [(String, Settings -> IO Formatter)]
named =
      [(String
"hlint", Settings -> IO Formatter
hlint), (String
"hindent", Settings -> IO Formatter
hindent), (String
"stylish-haskell", Settings -> IO Formatter
stylish)]

format :: Formatter -> HaskellSource -> Either String Reformatted
format :: Formatter -> HaskellSource -> Either String Reformatted
format = Formatter -> HaskellSource -> Either String Reformatted
unFormatter