{-# LANGUAGE OverloadedStrings #-}

module Hie.Yaml
  ( hieYaml,
    fmtComponent,
    fmtPkgs,
    cabalComponent,
    stackComponent,
  )
where

import qualified Data.Text as T
import Hie.Cabal.Parser

hieYaml :: String -> String -> String
hieYaml :: [Char] -> [Char] -> [Char]
hieYaml [Char]
sOrC [Char]
pkgs =
  [Char]
"cradle:\n"
    forall a. Semigroup a => a -> a -> a
<> [Char] -> [Char]
indent'
      ([Char]
sOrC forall a. Semigroup a => a -> a -> a
<> [Char]
":\n" forall a. Semigroup a => a -> a -> a
<> [Char] -> [Char]
indent' [Char]
pkgs)

indent' :: String -> String
indent' :: [Char] -> [Char]
indent' =
  [[Char]] -> [Char]
unlines
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map
      ( \[Char]
l -> case [Char]
l of
          [Char]
"" -> [Char]
""
          [Char]
_ -> [Char]
"  " forall a. Semigroup a => a -> a -> a
<> [Char]
l
      )
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[Char]]
lines

cabalComponent :: Name -> Component -> (FilePath, String)
cabalComponent :: Name -> Component -> ([Char], [Char])
cabalComponent Name
n (Comp CompType
Lib Name
"" Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
"lib:" forall a. Semigroup a => a -> a -> a
<> Name
n)
cabalComponent Name
n (Comp CompType
Lib Name
cn Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":lib:" forall a. Semigroup a => a -> a -> a
<> Name
cn)
cabalComponent Name
n (Comp CompType
Exe Name
cn Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":exe:" forall a. Semigroup a => a -> a -> a
<> Name
cn)
cabalComponent Name
n (Comp CompType
Bench Name
cn Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":bench:" forall a. Semigroup a => a -> a -> a
<> Name
cn)
cabalComponent Name
n (Comp CompType
Test Name
cn Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":test:" forall a. Semigroup a => a -> a -> a
<> Name
cn)

stackComponent :: Name -> Component -> (FilePath, String)
stackComponent :: Name -> Component -> ([Char], [Char])
stackComponent Name
n (Comp CompType
Lib Name
"" Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":lib")
stackComponent Name
n (Comp CompType
Lib Name
cn Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":lib:" forall a. Semigroup a => a -> a -> a
<> Name
cn)
stackComponent Name
n (Comp CompType
Exe Name
cn Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":exe:" forall a. Semigroup a => a -> a -> a
<> Name
cn)
stackComponent Name
n (Comp CompType
Bench Name
cn Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":bench:" forall a. Semigroup a => a -> a -> a
<> Name
cn)
stackComponent Name
n (Comp CompType
Test Name
cn Name
p) = (Name -> [Char]
T.unpack Name
p, Name -> [Char]
T.unpack forall a b. (a -> b) -> a -> b
$ Name
n forall a. Semigroup a => a -> a -> a
<> Name
":test:" forall a. Semigroup a => a -> a -> a
<> Name
cn)

fmtComponent :: (FilePath, String) -> String
fmtComponent :: ([Char], [Char]) -> [Char]
fmtComponent ([Char]
p, [Char]
c) =
  [Char]
"- path: "
    forall a. Semigroup a => a -> a -> a
<> [Char] -> [Char]
dQuote [Char]
p
    forall a. Semigroup a => a -> a -> a
<> [Char]
"\n  "
    forall a. Semigroup a => a -> a -> a
<> [Char]
"component: "
    forall a. Semigroup a => a -> a -> a
<> [Char] -> [Char]
dQuote [Char]
c

-- | Same as init but handle empty list without throwing errors.
dropLast :: [a] -> [a]
dropLast :: forall a. [a] -> [a]
dropLast [a]
l = forall a. Int -> [a] -> [a]
take (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l forall a. Num a => a -> a -> a
- Int
1) [a]
l

fmtPkgs :: String -> [Package] -> String
fmtPkgs :: [Char] -> [Package] -> [Char]
fmtPkgs [Char]
sOrC [Package]
pkgs = forall a. [a] -> [a]
dropLast forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines [[Char]]
l
  where
    comp :: Name -> Component -> ([Char], [Char])
comp = if [Char]
sOrC forall a. Eq a => a -> a -> Bool
== [Char]
"cabal" then Name -> Component -> ([Char], [Char])
cabalComponent else Name -> Component -> ([Char], [Char])
stackComponent
    f :: Package -> [[Char]]
f (Package Name
n [Component]
cs) = forall a b. (a -> b) -> [a] -> [b]
map ((forall a. Semigroup a => a -> a -> a
<> [Char]
"\n") forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], [Char]) -> [Char]
fmtComponent forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Component -> ([Char], [Char])
comp Name
n) [Component]
cs
    l :: [[Char]]
l = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Package -> [[Char]]
f [Package]
pkgs

dQuote :: String -> String
dQuote :: [Char] -> [Char]
dQuote [Char]
t = Char
'"' forall a. a -> [a] -> [a]
: [Char]
t forall a. Semigroup a => a -> a -> a
<> [Char]
"\""