{-|
This module implements the common `Option` type for from blocks and command-line optional arguments representation, and its parsers.
-}
module Lsql.Csv.Lang.Options (optionParser, 
  Option(Delimiter, SecondaryDelimiter, Quote, Named)) where

import System.Environment

import Text.Parsec
import Text.Parsec.Prim
import Text.Parsec.Combinator
import Text.Parsec.Text
import Text.Parsec.Char

char_option_p :: Parser Char
char_option_p :: Parser Char
char_option_p = do
  Char
ret <- Parser Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
  Char -> Parser Char
forall a. a -> ParsecT Text () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
ret


delOp :: String -> Parser Char
delOp :: String -> Parser Char
delOp String
opt = do
  String -> ParsecT Text () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
opt
  Char
c <- Parser Char
char_option_p
  Char -> Parser Char
forall a. a -> ParsecT Text () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
c

-- | The `Option` datatype for representing from block and command-line optional arguments.
data Option = Delimiter Char | SecondaryDelimiter Char | Quote Char | Named Bool

primaryDelOp :: ParsecT Text () Identity Option
primaryDelOp = do
  Char
r <- (Parser Char -> Parser Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try(Parser Char -> Parser Char) -> Parser Char -> Parser Char
forall a b. (a -> b) -> a -> b
$ String -> Parser Char
delOp String
"-d") Parser Char -> Parser Char -> Parser Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> Parser Char
delOp String
"--delimiter="
  Option -> ParsecT Text () Identity Option
forall a. a -> ParsecT Text () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Option -> ParsecT Text () Identity Option)
-> Option -> ParsecT Text () Identity Option
forall a b. (a -> b) -> a -> b
$ Char -> Option
Delimiter Char
r

secondaryDelOp :: ParsecT Text () Identity Option
secondaryDelOp = do
  Char
r <- (Parser Char -> Parser Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try(Parser Char -> Parser Char) -> Parser Char -> Parser Char
forall a b. (a -> b) -> a -> b
$ String -> Parser Char
delOp String
"-s") Parser Char -> Parser Char -> Parser Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> Parser Char
delOp String
"--secondary-delimiter="
  Option -> ParsecT Text () Identity Option
forall a. a -> ParsecT Text () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Option -> ParsecT Text () Identity Option)
-> Option -> ParsecT Text () Identity Option
forall a b. (a -> b) -> a -> b
$ Char -> Option
SecondaryDelimiter Char
r


notNamedOp :: ParsecT Text u Identity Bool
notNamedOp = do
  (ParsecT Text u Identity String -> ParsecT Text u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try(ParsecT Text u Identity String -> ParsecT Text u Identity String)
-> ParsecT Text u Identity String -> ParsecT Text u Identity String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"-N") ParsecT Text u Identity String
-> ParsecT Text u Identity String -> ParsecT Text u Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"--not-named"
  Bool -> ParsecT Text u Identity Bool
forall a. a -> ParsecT Text u Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

namedOp :: ParsecT Text u Identity Bool
namedOp = do
  (ParsecT Text u Identity String -> ParsecT Text u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try(ParsecT Text u Identity String -> ParsecT Text u Identity String)
-> ParsecT Text u Identity String -> ParsecT Text u Identity String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"-n") ParsecT Text u Identity String
-> ParsecT Text u Identity String -> ParsecT Text u Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"--named"
  Bool -> ParsecT Text u Identity Bool
forall a. a -> ParsecT Text u Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True

nameOp :: ParsecT Text u Identity Option
nameOp = do
  Bool
r <- (ParsecT Text u Identity Bool -> ParsecT Text u Identity Bool
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try(ParsecT Text u Identity Bool -> ParsecT Text u Identity Bool)
-> ParsecT Text u Identity Bool -> ParsecT Text u Identity Bool
forall a b. (a -> b) -> a -> b
$ ParsecT Text u Identity Bool
forall {u}. ParsecT Text u Identity Bool
namedOp) ParsecT Text u Identity Bool
-> ParsecT Text u Identity Bool -> ParsecT Text u Identity Bool
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Text u Identity Bool
forall {u}. ParsecT Text u Identity Bool
notNamedOp
  Option -> ParsecT Text u Identity Option
forall a. a -> ParsecT Text u Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Option -> ParsecT Text u Identity Option)
-> Option -> ParsecT Text u Identity Option
forall a b. (a -> b) -> a -> b
$ Bool -> Option
Named Bool
r

-- | The `Option` parser monad for parsing from block and command-line optional arguments.
optionParser :: Parser Option
optionParser :: ParsecT Text () Identity Option
optionParser = (ParsecT Text () Identity Option -> ParsecT Text () Identity Option
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT Text () Identity Option
primaryDelOp) ParsecT Text () Identity Option
-> ParsecT Text () Identity Option
-> ParsecT Text () Identity Option
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT Text () Identity Option -> ParsecT Text () Identity Option
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT Text () Identity Option
secondaryDelOp) ParsecT Text () Identity Option
-> ParsecT Text () Identity Option
-> ParsecT Text () Identity Option
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Text () Identity Option
forall {u}. ParsecT Text u Identity Option
nameOp