aboutsummaryrefslogtreecommitdiffhomepage
path: root/scaffolder/src/Text/Edifact/Scaffolder/Composites/Specification.hs
blob: 0bb749d059ca30ba805b897e86ec73b34eb81ac4 (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
module Text.Edifact.Scaffolder.Composites.Specification
  ( -- *
    specificationParser
  , listSimples
  ) where

import           Text.Edifact.Scaffolder.Commons
import           Text.Edifact.Scaffolder.Composites.Types

import           Text.Parsec                              as P (anyChar, count,
                                                                digit,
                                                                endOfLine, many,
                                                                many1, manyTill,
                                                                oneOf, skipMany,
                                                                string, try,
                                                                (<?>))
import           Text.Parsec.String                       (Parser)

specificationParser :: Parser ((CompositeCode, CompositeName), [Dependency])
specificationParser = do
  compositeInfo <- scanUntil [ compositeParser ]
  dependencies <- scan [ inLine dependencyParser ] <?> "Composites specification"
  pure (compositeInfo, dependencies)

listSimples :: Parser (CompositeCode, [SimpleCode])
listSimples = do
  parsed <- specificationParser
  pure (fst $ fst parsed, getElementSimpleCode . dependencyElement <$> snd parsed)

compositeParser :: Parser (CompositeCode, CompositeName)
compositeParser = do
  _ <- count 6 (oneOf "+*#|X ")
  skipMany (string " ")
  code <- compositeCodeParser
  _ <- string " "
  name <- CompositeName <$> manyTill anyChar (() <$ try endOfLine)
  pure (code, name)

compositeCodeParser :: Parser CompositeCode
compositeCodeParser = do
  initial <- oneOf "CE"
  rest <- count 3 digit
  pure (fromString (initial : rest))

dependencyParser :: Parser Dependency
dependencyParser =
  Dependency <$> positionParser
             <*  many1 (oneOf "+*#|-X ")
             <*> elementParser
             <*  stringToPresenceParser
             <*  many1 (string " ")
             <*> presenceParser
             <?> "Dependency"

inLine :: Parser a -> Parser [a]
inLine p = single (many (string " ") *> p <* filler)

filler :: Parser ()
filler = () <$ many (oneOf "an.0123456789 ")

positionParser :: Parser Position
positionParser =
  fromString <$> count 3 digit
             <?> "Position"

elementParser :: Parser Element
elementParser =
  fromString <$> count 4 digit
             <?> "Element"