aboutsummaryrefslogtreecommitdiffhomepage
path: root/scaffolder/src/Text/Edifact/BundleReader/Commons.hs
blob: 0c8334a550c5b1d0b3701a05f83003cd58952d34 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
{-# LANGUAGE OverloadedStrings #-}

module Text.Edifact.BundleReader.Commons where

import           Text.Edifact.BundleReader.Configuration
import           Text.Edifact.Scaffolder.Commons

import           Control.Monad.Reader                    (ReaderT, runReaderT)
import           Data.ByteString                         (ByteString)
import           Data.Char                               (toLower)
import           Data.List.Split                         (splitWhen)
import           Data.Text                               as T (isInfixOf, lines,
                                                               map, null,
                                                               replicate, strip,
                                                               unlines, unpack)
import           Data.Text.Encoding                      as TE (decodeLatin1,
                                                                decodeUtf8')
import           Data.Text.IO                            as TIO (writeFile)
import           Formatting
import           Text.Parsec                             (Parsec, runParser)

type BundleReader = ReaderT BundleReaderEnv IO

decodeContent :: ByteString -> Text
decodeContent content = either (const $ cleanupAsciiArt $ decodeLatin1 content) id (decodeUtf8' content)

splitFileByDash :: Int -> Text -> [Text]
splitFileByDash n =
  let separator = T.replicate n "-"
      isNotEmpty = not . T.null . T.strip
  in
    filter isNotEmpty . fmap T.unlines . splitWhen (separator `T.isInfixOf`) . T.lines

runBundleReader :: BundleReader () -> BundleReaderEnv -> IO ()
runBundleReader = runReaderT

getOutputFile :: Format String (a -> String) -> FilePath -> a -> BundleReader FilePath
getOutputFile f d c = do
  home <- getSpecificationHome
  pure (formatToString (string % "/" % string % "/" % f) home d c)

getSpecificationHome :: BundleReader FilePath
getSpecificationHome = do
  home <- getHome
  rev <- getTargetRevision
  pure (home </> formatToString fRevision rev)

toFile :: Text -> FilePath -> BundleReader ()
toFile specification outputFile = liftIO (TIO.writeFile outputFile specification)

parseOrFail :: (Monoid u) => Text -> Parsec String u a -> BundleReader a
parseOrFail specification parser = either (error . (\a -> show specification <> show a)) pure (runParser parser mempty "" (T.unpack specification))

toFileWithParser :: (Monoid a, Monoid u) => Text -> FilePath -> Parsec String u a -> BundleReader a
toFileWithParser specification outputFile parser = do
  liftIO (TIO.writeFile outputFile specification)
  either (error . show) pure (runParser parser mempty "" (T.unpack specification))

lower :: Format r (String -> r)
lower = mapf (fmap toLower) string

fRevision :: Format r (Revision -> r)
fRevision = mapf getRevision string

fRevisionLower :: Format r (Revision -> r)
fRevisionLower = mapf getRevision lower

fMessageCodeLower :: Format r (MessageCode -> r)
fMessageCodeLower = mapf getMessageCode lower

fSegmentCodeLower :: Format r (SegmentCode -> r)
fSegmentCodeLower = mapf getSegmentCode lower

fCompositeCodeLower :: Format r (CompositeCode -> r)
fCompositeCodeLower = mapf getCompositeCode lower

fSimpleCodeLower :: Format r (SimpleCode -> r)
fSimpleCodeLower = mapf getSimpleCode lower

-- This might not be the proper way to do it...
-- Use Data.Text.Encoding.decodeUtf8With instead?
cleanupAsciiArt :: Text -> Text
cleanupAsciiArt =
  let f 'Ä' = '-'
      f '¿' = '+'
      f '³' = '|'
      f 'Ù' = '+'
      f 'Á' = '+'
      f c   = c
  in T.map f