module Utils.String where

import Data.Foldable.Extra (Foldable (fold))
import Data.List           (intercalate)
import Data.Monoid.HT      (when)
import Utils.Foldable      (hasSome, wrapMaybe)
import Utils.List          (safeLast)


wrap :: String -> String -> String -> String
wrap :: [Char] -> [Char] -> [Char] -> [Char]
wrap [Char]
beg [Char]
end [Char]
x = forall m. Monoid m => Bool -> m -> m
when (forall (t :: * -> *) a. Foldable t => t a -> Bool
hasSome [Char]
x) forall a b. (a -> b) -> a -> b
$ [Char]
beg forall a. [a] -> [a] -> [a]
++ [Char]
x forall a. [a] -> [a] -> [a]
++ [Char]
end

wrapBoth :: String -> String -> String
wrapBoth :: [Char] -> [Char] -> [Char]
wrapBoth [Char]
x = [Char] -> [Char] -> [Char] -> [Char]
wrap [Char]
x [Char]
x

wrapParens :: String -> String
wrapParens :: [Char] -> [Char]
wrapParens = [Char] -> [Char] -> [Char] -> [Char]
wrap [Char]
"(" [Char]
")"

wrapSquare :: String -> String
wrapSquare :: [Char] -> [Char]
wrapSquare = [Char] -> [Char] -> [Char] -> [Char]
wrap [Char]
"[" [Char]
"]"

wrapCurly :: String -> String
wrapCurly :: [Char] -> [Char]
wrapCurly = [Char] -> [Char] -> [Char] -> [Char]
wrap [Char]
"{" [Char]
"}"

wrapSpaces :: String -> String
wrapSpaces :: [Char] -> [Char]
wrapSpaces = [Char] -> [Char] -> [Char]
wrapBoth [Char]
" "

wrapQuotes :: String -> String
wrapQuotes :: [Char] -> [Char]
wrapQuotes = [Char] -> [Char] -> [Char]
wrapBoth [Char]
"'"

wrapBackQuotes :: String -> String
wrapBackQuotes :: [Char] -> [Char]
wrapBackQuotes = [Char] -> [Char] -> [Char]
wrapBoth [Char]
"`"

wrapDoubleQuotes :: String -> String
wrapDoubleQuotes :: [Char] -> [Char]
wrapDoubleQuotes = [Char] -> [Char] -> [Char]
wrapBoth [Char]
"\""


wrap' :: String -> String -> String -> String
wrap' :: [Char] -> [Char] -> [Char] -> [Char]
wrap' [Char]
beg [Char]
end [Char]
x = [Char]
beg forall a. [a] -> [a] -> [a]
++ [Char]
x forall a. [a] -> [a] -> [a]
++ [Char]
end

wrapBoth' :: String -> String -> String
wrapBoth' :: [Char] -> [Char] -> [Char]
wrapBoth' [Char]
x = [Char] -> [Char] -> [Char] -> [Char]
wrap' [Char]
x [Char]
x

wrapParens' :: String -> String
wrapParens' :: [Char] -> [Char]
wrapParens' = [Char] -> [Char] -> [Char] -> [Char]
wrap' [Char]
"(" [Char]
")"

wrapCurly' :: String -> String
wrapCurly' :: [Char] -> [Char]
wrapCurly' = [Char] -> [Char] -> [Char] -> [Char]
wrap' [Char]
"{" [Char]
"}"

wrapQuotes' :: String -> String
wrapQuotes' :: [Char] -> [Char]
wrapQuotes' = [Char] -> [Char] -> [Char]
wrapBoth' [Char]
"'"

wrapDoubleQuotes' :: String -> String
wrapDoubleQuotes' :: [Char] -> [Char]
wrapDoubleQuotes' = [Char] -> [Char] -> [Char]
wrapBoth' [Char]
"\""


wrapCsv :: Show a => [a] -> String
wrapCsv :: forall a. Show a => [a] -> [Char]
wrapCsv []  = forall a. Monoid a => a
mempty
wrapCsv [a
x] = forall a. Show a => a -> [Char]
show a
x
wrapCsv [a]
x   = forall a. Show a => [a] -> [Char]
wrapParensCsv [a]
x

wrapParensCsv :: Show a => [a] -> String
wrapParensCsv :: forall a. Show a => [a] -> [Char]
wrapParensCsv = [Char] -> [Char]
wrapParens forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
", "

wrapSquareCsv :: Show a => [a] -> String
wrapSquareCsv :: forall a. Show a => [a] -> [Char]
wrapSquareCsv = [Char] -> [Char]
wrapSquare forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
", "

wrapCurlyCsv :: Show a => [a] -> String
wrapCurlyCsv :: forall a. Show a => [a] -> [Char]
wrapCurlyCsv = [Char] -> [Char]
wrapCurly forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
", "

wrapLetContext :: (Show a, Show b) => [a] -> b -> String
wrapLetContext :: forall a b. (Show a, Show b) => [a] -> b -> [Char]
wrapLetContext [a]
x b
y = [Char] -> [Char]
wrapContext forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
wrapBoth [Char]
"\n\n" (forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
"\n" [a]
x) forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show b
y


wrapBlock :: Show a => [a] -> String
wrapBlock :: forall a. Show a => [a] -> [Char]
wrapBlock [a]
x = [Char] -> [Char]
wrapContext forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
wrapBoth [Char]
"\n" forall a b. (a -> b) -> a -> b
$ forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
"\n" [a]
x

wrapSpacedBlock :: Show a => [a] -> String
wrapSpacedBlock :: forall a. Show a => [a] -> [Char]
wrapSpacedBlock [a]
x = [Char] -> [Char]
wrapContext forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
wrapBoth [Char]
"\n\n" forall a b. (a -> b) -> a -> b
$ forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
"\n\n" [a]
x

wrapSingleBlock :: Show a => a -> String
wrapSingleBlock :: forall a. Show a => a -> [Char]
wrapSingleBlock a
x = [Char] -> [Char]
wrapContext forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
wrapBoth [Char]
"\n" forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> [Char]
show a
x

wrapContext :: String -> String
wrapContext :: [Char] -> [Char]
wrapContext = forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> [Char] -> [Char]
indent Int
2 <$>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[Char]]
lines
  where
    indent :: Int -> [Char] -> [Char]
indent Int
n [Char]
x = forall m. Monoid m => Bool -> m -> m
when (forall (t :: * -> *) a. Foldable t => t a -> Bool
hasSome [Char]
x) (forall a. Int -> a -> [a]
replicate Int
n Char
' ' forall a. [a] -> [a] -> [a]
++ [Char]
x)

wrapNewLines :: String -> String
wrapNewLines :: [Char] -> [Char]
wrapNewLines = ([Char]
"\n" ++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. [a] -> [a] -> [a]
++ [Char]
"\n")



str :: Show a => String -> [a] -> String
str :: forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
sep [a]
xs = forall a. [a] -> [[a]] -> [a]
intercalate [Char]
sep forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> [Char]
show forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
xs

strs :: [String] -> [String] -> String
strs :: [[Char]] -> [[Char]] -> [Char]
strs [[Char]]
seps [[Char]]
xs = forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold [[Char]]
elems forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold (forall a. [a] -> Maybe a
safeLast [[Char]]
xs)
  where
    elems :: [[Char]]
elems = do ([Char]
x, [Char]
sep) <- forall a b. [a] -> [b] -> [(a, b)]
zip [[Char]]
xs [[Char]]
seps
               forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ [Char]
x forall a. [a] -> [a] -> [a]
++ [Char]
sep

joinWords :: [String] -> String
joinWords :: [[Char]] -> [Char]
joinWords [[Char]]
x = [[Char]] -> [Char]
unwords forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter forall (t :: * -> *) a. Foldable t => t a -> Bool
hasSome [[Char]]
x

joinLines :: [String] -> String
joinLines :: [[Char]] -> [Char]
joinLines [[Char]]
x = forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"\n\n\n" forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter forall (t :: * -> *) a. Foldable t => t a -> Bool
hasSome [[Char]]
x

joinMaybe :: Show a => String -> Maybe a -> String
joinMaybe :: forall a. Show a => [Char] -> Maybe a -> [Char]
joinMaybe [Char]
start Maybe a
x = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (([Char]
start +++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show) Maybe a
x

joinMaybePost :: Show a => Maybe a -> String ->  String
joinMaybePost :: forall a. Show a => Maybe a -> [Char] -> [Char]
joinMaybePost Maybe a
x [Char]
end = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (([Char] -> [Char] -> [Char]
+++ [Char]
end) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show) Maybe a
x

joinList :: Show a => String -> String -> [a] -> String
joinList :: forall a. Show a => [Char] -> [Char] -> [a] -> [Char]
joinList [Char]
start [Char]
sep [a]
x = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (([Char]
start +++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
sep) (forall (t :: * -> *) a. Foldable t => t a -> Maybe (t a)
wrapMaybe [a]
x)

joinListPost :: Show a => String -> [a] -> String -> String
joinListPost :: forall a. Show a => [Char] -> [a] -> [Char] -> [Char]
joinListPost [Char]
sep [a]
x [Char]
end = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (([Char] -> [Char] -> [Char]
+++ [Char]
end) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => [Char] -> [a] -> [Char]
str [Char]
sep) (forall (t :: * -> *) a. Foldable t => t a -> Maybe (t a)
wrapMaybe [a]
x)


(+++) :: String -> String -> String
+++ :: [Char] -> [Char] -> [Char]
(+++) [Char]
x [Char]
y = [Char]
x forall a. [a] -> [a] -> [a]
++ [Char]
" " forall a. [a] -> [a] -> [a]
++ [Char]
y

data Wrapper
  = Wrapper String

instance Show Wrapper where
  show :: Wrapper -> [Char]
show (Wrapper [Char]
x) = [Char]
x

data Empty
  = Empty

instance Show Empty where
  show :: Empty -> [Char]
show Empty
Empty = forall a. Monoid a => a
mempty