--- * -*- outline-regexp:"--- \\*"; -*-
--- ** doc
{-|

CSV utilities.

-}

--- ** language
{-# LANGUAGE OverloadedStrings    #-}

--- ** exports
module Hledger.Read.CsvUtils (
  CSV, CsvRecord, CsvValue,
  printCSV,
  printTSV,
  -- * Tests
  tests_CsvUtils,
)
where

--- ** imports
import Prelude hiding (Applicative(..))
import Data.List (intersperse)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TB

import Hledger.Utils

--- ** doctest setup
-- $setup
-- >>> :set -XOverloadedStrings

type CSV       = [CsvRecord]
type CsvRecord = [CsvValue]
type CsvValue  = Text

printCSV :: [CsvRecord] -> TL.Text
printCSV :: [CsvRecord] -> Text
printCSV = Builder -> Text
TB.toLazyText forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Builder] -> Builder
unlinesB forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map CsvRecord -> Builder
printRecord
    where printRecord :: CsvRecord -> Builder
printRecord = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Text -> Builder
TB.fromText forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse Text
"," forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
printField
          printField :: Text -> Text
printField = Text -> Text -> Text -> Text
wrap Text
"\"" Text
"\"" forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> Text -> Text
T.replace Text
"\"" Text
"\"\""

printTSV :: [CsvRecord] -> TL.Text
printTSV :: [CsvRecord] -> Text
printTSV = Builder -> Text
TB.toLazyText forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Builder] -> Builder
unlinesB forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map CsvRecord -> Builder
printRecord
    where printRecord :: CsvRecord -> Builder
printRecord = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Text -> Builder
TB.fromText forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse Text
"\t" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
printField
          printField :: Text -> Text
printField = (Char -> Char) -> Text -> Text
T.map Char -> Char
replaceWhitespace
          replaceWhitespace :: Char -> Char
replaceWhitespace Char
c | Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'\t', Char
'\n', Char
'\r'] = Char
' '
          replaceWhitespace Char
c = Char
c

--- ** tests

tests_CsvUtils :: TestTree
tests_CsvUtils :: TestTree
tests_CsvUtils = [Char] -> [TestTree] -> TestTree
testGroup [Char]
"CsvUtils" [
  ]