{-# LANGUAGE OverloadedStrings #-}

module Skeletest.Internal.Utils.Text (
  showT,
  pluralize,
  parens,

  -- * Indentation
  IndentSize,
  IndentLevel,
  indent,
  indentWith,
) where

import Data.Text (Text)
import Data.Text qualified as Text

-- TODO: Remove when Text.show is available in the version of 'text' that's
-- shipped with the lowest version of GHC we support.
showT :: (Show a) => a -> Text
showT :: forall a. Show a => a -> Text
showT = String -> Text
Text.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show

pluralize :: (Num a, Eq a, Show a) => a -> Text -> Text
pluralize :: forall a. (Num a, Eq a, Show a) => a -> Text -> Text
pluralize a
n Text
item = a -> Text
forall a. Show a => a -> Text
showT a
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
item Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (if a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
1 then Text
"" else Text
"s")

-- | Add parentheses if the given input contains spaces.
parens :: Text -> Text
parens :: Text -> Text
parens Text
s =
  if Text
" " Text -> Text -> Bool
`Text.isInfixOf` Text
s
    then Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
    else Text
s

indent :: Text -> Text
indent :: Text -> Text
indent = Int -> Text -> Int -> Text -> Text
indentWith Int
2 Text
" " Int
1

type IndentSize = Int
type IndentLevel = Int

indentWith :: IndentSize -> Text -> IndentLevel -> Text -> Text
indentWith :: Int -> Text -> Int -> Text -> Text
indentWith Int
indentSize Text
fill Int
lvl =
  Text -> [Text] -> Text
Text.intercalate Text
"\n"
    ([Text] -> Text) -> (Text -> [Text]) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Text -> Text
Text.replicate (Int
lvl Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
indentSize) Text
fill <>)
    ([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> [Text]
Text -> Text -> [Text]
Text.splitOn Text
"\n"