{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}

module Program.Mighty.Config (
  -- * Parsing a configuration file.
    parseOption
#ifdef DHALL
  , parseOptionDhall
#else
  , Natural
#endif
  -- * Creating 'Option'.
  , defaultOption
  -- * Types
  , Option(..)
  ) where

import Data.List.Split (splitOn)
import Text.Parsec
import Text.Parsec.ByteString.Lazy
#ifdef DHALL
import Data.String (fromString)
import qualified Data.Text as T
import Dhall(Generic, Natural, input, auto, FromDhall)
import qualified Program.Mighty.Dhall.Option as Do

#else
import Program.Mighty.Types
#endif

import Program.Mighty.Parser

----------------------------------------------------------------

data Option = Option {
    Option -> Natural
opt_port :: Natural
  , Option -> String
opt_host :: String
  , Option -> Bool
opt_debug_mode :: Bool
  , Option -> String
opt_user  :: String
  , Option -> String
opt_group :: String
  , Option -> String
opt_pid_file    :: FilePath
  , Option -> String
opt_report_file :: FilePath
  , Option -> Bool
opt_logging :: Bool
  , Option -> String
opt_log_file :: FilePath
  , Option -> Natural
opt_log_file_size :: Natural
  , Option -> Natural
opt_log_backup_number :: Natural
  , Option -> String
opt_index_file :: FilePath
  , Option -> String
opt_index_cgi  :: FilePath
  , Option -> String
opt_status_file_dir :: FilePath
  , Option -> Natural
opt_connection_timeout :: Natural
  , Option -> Natural
opt_proxy_timeout      :: Natural
  , Option -> Natural
opt_fd_cache_duration  :: Natural
  , Option -> Natural
opt_service :: Natural
  , Option -> Natural
opt_tls_port :: Natural
  , Option -> String
opt_tls_cert_file   :: FilePath
  , Option -> String
opt_tls_chain_files :: FilePath
  , Option -> String
opt_tls_key_file    :: FilePath
  , Option -> Natural
opt_quic_port :: Natural
  , Option -> [String]
opt_quic_addr :: [String]
  , Option -> Maybe String
opt_quic_debug_dir :: Maybe FilePath
  , Option -> Maybe String
opt_quic_qlog_dir  :: Maybe FilePath
  , Option -> String
opt_server_name :: String
  , Option -> Maybe String
opt_routing_file :: Maybe String
#ifdef DHALL
} deriving (Eq, Show, Generic)
#else
} deriving (Option -> Option -> Bool
(Option -> Option -> Bool)
-> (Option -> Option -> Bool) -> Eq Option
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Option -> Option -> Bool
$c/= :: Option -> Option -> Bool
== :: Option -> Option -> Bool
$c== :: Option -> Option -> Bool
Eq, Natural -> Option -> ShowS
[Option] -> ShowS
Option -> String
(Natural -> Option -> ShowS)
-> (Option -> String) -> ([Option] -> ShowS) -> Show Option
forall a.
(Natural -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Option] -> ShowS
$cshowList :: [Option] -> ShowS
show :: Option -> String
$cshow :: Option -> String
showsPrec :: Natural -> Option -> ShowS
$cshowsPrec :: Natural -> Option -> ShowS
Show)
#endif

#ifdef DHALL
instance FromDhall Option
#endif

-- | Getting a default 'Option'.
defaultOption :: Option
defaultOption :: Option
defaultOption = Option :: Natural
-> String
-> Bool
-> String
-> String
-> String
-> String
-> Bool
-> String
-> Natural
-> Natural
-> String
-> String
-> String
-> Natural
-> Natural
-> Natural
-> Natural
-> Natural
-> String
-> String
-> String
-> Natural
-> [String]
-> Maybe String
-> Maybe String
-> String
-> Maybe String
-> Option
Option {
    opt_port :: Natural
opt_port = Natural
8080
  , opt_host :: String
opt_host = String
"*"
  , opt_debug_mode :: Bool
opt_debug_mode = Bool
True
  , opt_user :: String
opt_user  = String
"root"
  , opt_group :: String
opt_group = String
"root"
  , opt_pid_file :: String
opt_pid_file    = String
"/var/run/mighty.pid"
  , opt_report_file :: String
opt_report_file = String
"/tmp/mighty_report"
  , opt_logging :: Bool
opt_logging = Bool
True
  , opt_log_file :: String
opt_log_file = String
"/var/log/mighty"
  , opt_log_file_size :: Natural
opt_log_file_size = Natural
16777216
  , opt_log_backup_number :: Natural
opt_log_backup_number = Natural
10
  , opt_index_file :: String
opt_index_file = String
"index.html"
  , opt_index_cgi :: String
opt_index_cgi  = String
"index.cgi"
  , opt_status_file_dir :: String
opt_status_file_dir = String
"/usr/local/share/mighty/status"
  , opt_connection_timeout :: Natural
opt_connection_timeout = Natural
30
  , opt_proxy_timeout :: Natural
opt_proxy_timeout      = Natural
0
  , opt_fd_cache_duration :: Natural
opt_fd_cache_duration  = Natural
10
  , opt_service :: Natural
opt_service = Natural
0
  , opt_tls_port :: Natural
opt_tls_port = Natural
443
  , opt_tls_cert_file :: String
opt_tls_cert_file   = String
"cert.pem"
  , opt_tls_chain_files :: String
opt_tls_chain_files = String
"chain.pem"
  , opt_tls_key_file :: String
opt_tls_key_file    = String
"privkey.pem"
  , opt_quic_port :: Natural
opt_quic_port = Natural
443
  , opt_quic_addr :: [String]
opt_quic_addr = [String
"127.0.0.1"]
  , opt_quic_debug_dir :: Maybe String
opt_quic_debug_dir = Maybe String
forall a. Maybe a
Nothing
  , opt_quic_qlog_dir :: Maybe String
opt_quic_qlog_dir  = Maybe String
forall a. Maybe a
Nothing
  , opt_server_name :: String
opt_server_name = String
"Dummy"
  , opt_routing_file :: Maybe String
opt_routing_file = Maybe String
forall a. Maybe a
Nothing
}

----------------------------------------------------------------
-- | Parsing a configuration file to get an 'Option'.
parseOption :: FilePath -> IO Option
parseOption :: String -> IO Option
parseOption String
file = Option -> [Conf] -> Option
makeOpt Option
defaultOption ([Conf] -> Option) -> IO [Conf] -> IO Option
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO [Conf]
parseConfig String
file

#ifdef DHALL
parseOptionDhall :: FilePath -> IO Option
parseOptionDhall = fmap optionFromDhall . input auto . fromString

optionFromDhall :: Do.Option -> Option
optionFromDhall o = Option
  { opt_port = Do.port o
  , opt_host = T.unpack $ Do.host o
  , opt_debug_mode = Do.debugMode o
  , opt_user  = T.unpack $ Do.user o
  , opt_group = T.unpack $ Do.group o
  , opt_pid_file    = T.unpack $ Do.pidFile o
  , opt_report_file = T.unpack $ Do.reportFile o
  , opt_logging = Do.logging o
  , opt_log_file = T.unpack $ Do.logFile o
  , opt_log_file_size = Do.logFileSize o
  , opt_log_backup_number = Do.logBackupNumber o
  , opt_index_file = T.unpack $ Do.indexFile o
  , opt_index_cgi  = T.unpack $ Do.indexCgi o
  , opt_status_file_dir = T.unpack $ Do.statusFileDir o
  , opt_connection_timeout = Do.connectionTimeout o
  , opt_proxy_timeout      = Do.proxyTimeout o
  , opt_fd_cache_duration  = Do.fdCacheDuration o
  , opt_service = Do.service o
  , opt_tls_port = Do.tlsPort o
  , opt_tls_cert_file   = T.unpack $ Do.tlsCertFile o
  , opt_tls_chain_files = T.unpack $ Do.tlsChainFiles o
  , opt_tls_key_file    = T.unpack $ Do.tlsKeyFile o
  , opt_quic_addr = T.unpack <$> Do.quicAddr o
  , opt_quic_port = Do.quicPort o
  , opt_quic_debug_dir = T.unpack <$> Do.quicDebugDir o
  , opt_quic_qlog_dir  = T.unpack <$> Do.quicQlogDir o
  , opt_server_name = "Dummy"
  , opt_routing_file = Nothing
}
#endif

----------------------------------------------------------------

makeOpt :: Option -> [Conf] -> Option
makeOpt :: Option -> [Conf] -> Option
makeOpt Option
def [Conf]
conf = Option :: Natural
-> String
-> Bool
-> String
-> String
-> String
-> String
-> Bool
-> String
-> Natural
-> Natural
-> String
-> String
-> String
-> Natural
-> Natural
-> Natural
-> Natural
-> Natural
-> String
-> String
-> String
-> Natural
-> [String]
-> Maybe String
-> Maybe String
-> String
-> Maybe String
-> Option
Option {
    opt_port :: Natural
opt_port               = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Port" Option -> Natural
opt_port
  , opt_host :: String
opt_host               = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Host" Option -> String
opt_host
  , opt_debug_mode :: Bool
opt_debug_mode         = String -> (Option -> Bool) -> Bool
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Debug_Mode" Option -> Bool
opt_debug_mode
  , opt_user :: String
opt_user               = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"User" Option -> String
opt_user
  , opt_group :: String
opt_group              = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Group" Option -> String
opt_group
  , opt_pid_file :: String
opt_pid_file           = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Pid_File" Option -> String
opt_pid_file
  , opt_report_file :: String
opt_report_file        = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Report_File" Option -> String
opt_report_file
  , opt_logging :: Bool
opt_logging            = String -> (Option -> Bool) -> Bool
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Logging" Option -> Bool
opt_logging
  , opt_log_file :: String
opt_log_file           = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Log_File" Option -> String
opt_log_file
  , opt_log_file_size :: Natural
opt_log_file_size      = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Log_File_Size" Option -> Natural
opt_log_file_size
  , opt_log_backup_number :: Natural
opt_log_backup_number  = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Log_Backup_Number" Option -> Natural
opt_log_backup_number
  , opt_index_file :: String
opt_index_file         = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Index_File" Option -> String
opt_index_file
  , opt_index_cgi :: String
opt_index_cgi          = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Index_Cgi" Option -> String
opt_index_cgi
  , opt_status_file_dir :: String
opt_status_file_dir    = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Status_File_Dir" Option -> String
opt_status_file_dir
  , opt_connection_timeout :: Natural
opt_connection_timeout = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Connection_Timeout" Option -> Natural
opt_connection_timeout
  , opt_proxy_timeout :: Natural
opt_proxy_timeout      = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Proxy_Timeout" Option -> Natural
opt_proxy_timeout
  , opt_fd_cache_duration :: Natural
opt_fd_cache_duration  = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Fd_Cache_Duration" Option -> Natural
opt_fd_cache_duration
  , opt_service :: Natural
opt_service            = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Service" Option -> Natural
opt_service
  , opt_tls_port :: Natural
opt_tls_port           = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Tls_Port" Option -> Natural
opt_tls_port
  , opt_tls_cert_file :: String
opt_tls_cert_file      = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Tls_Cert_File" Option -> String
opt_tls_cert_file
  , opt_tls_chain_files :: String
opt_tls_chain_files    = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Tls_Chain_Files" Option -> String
opt_tls_chain_files
  , opt_tls_key_file :: String
opt_tls_key_file       = String -> (Option -> String) -> String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Tls_Key_File" Option -> String
opt_tls_key_file
  , opt_quic_addr :: [String]
opt_quic_addr          = String -> (Option -> [String]) -> [String]
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Quic_Addr" Option -> [String]
opt_quic_addr
  , opt_quic_port :: Natural
opt_quic_port          = String -> (Option -> Natural) -> Natural
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Quic_Port" Option -> Natural
opt_quic_port
  , opt_quic_debug_dir :: Maybe String
opt_quic_debug_dir     = String -> (Option -> Maybe String) -> Maybe String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Quic_Debug_Dir" Option -> Maybe String
opt_quic_debug_dir
  , opt_quic_qlog_dir :: Maybe String
opt_quic_qlog_dir      = String -> (Option -> Maybe String) -> Maybe String
forall b. FromConf b => String -> (Option -> b) -> b
get String
"Quic_Qlog_Dir" Option -> Maybe String
opt_quic_qlog_dir
  , opt_server_name :: String
opt_server_name        = String
"Dummy"
  , opt_routing_file :: Maybe String
opt_routing_file       = Maybe String
forall a. Maybe a
Nothing
  }
  where
    get :: String -> (Option -> b) -> b
get String
k Option -> b
func = b -> (ConfValue -> b) -> Maybe ConfValue -> b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Option -> b
func Option
def) ConfValue -> b
forall a. FromConf a => ConfValue -> a
fromConf (Maybe ConfValue -> b) -> Maybe ConfValue -> b
forall a b. (a -> b) -> a -> b
$ String -> [Conf] -> Maybe ConfValue
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
k [Conf]
conf

----------------------------------------------------------------

type Conf = (String, ConfValue)

data ConfValue = CV_Natural Natural | CV_Bool Bool | CV_String String deriving (ConfValue -> ConfValue -> Bool
(ConfValue -> ConfValue -> Bool)
-> (ConfValue -> ConfValue -> Bool) -> Eq ConfValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConfValue -> ConfValue -> Bool
$c/= :: ConfValue -> ConfValue -> Bool
== :: ConfValue -> ConfValue -> Bool
$c== :: ConfValue -> ConfValue -> Bool
Eq,Natural -> ConfValue -> ShowS
[ConfValue] -> ShowS
ConfValue -> String
(Natural -> ConfValue -> ShowS)
-> (ConfValue -> String)
-> ([ConfValue] -> ShowS)
-> Show ConfValue
forall a.
(Natural -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConfValue] -> ShowS
$cshowList :: [ConfValue] -> ShowS
show :: ConfValue -> String
$cshow :: ConfValue -> String
showsPrec :: Natural -> ConfValue -> ShowS
$cshowsPrec :: Natural -> ConfValue -> ShowS
Show)

class FromConf a where
    fromConf :: ConfValue -> a

instance FromConf Natural where
    fromConf :: ConfValue -> Natural
fromConf (CV_Natural Natural
n) = Natural
n
    fromConf ConfValue
_ = String -> Natural
forall a. HasCallStack => String -> a
error String
"fromConf int"

instance FromConf Bool where
    fromConf :: ConfValue -> Bool
fromConf (CV_Bool Bool
b) = Bool
b
    fromConf ConfValue
_ = String -> Bool
forall a. HasCallStack => String -> a
error String
"fromConf bool"

instance FromConf String where
    fromConf :: ConfValue -> String
fromConf (CV_String String
s) = String
s
    fromConf ConfValue
_ = ShowS
forall a. HasCallStack => String -> a
error String
"fromConf string"

instance FromConf (Maybe String) where
    fromConf :: ConfValue -> Maybe String
fromConf (CV_String String
"") = Maybe String
forall a. Maybe a
Nothing
    fromConf (CV_String String
s)  = String -> Maybe String
forall a. a -> Maybe a
Just String
s
    fromConf ConfValue
_ = String -> Maybe String
forall a. HasCallStack => String -> a
error String
"fromConf string"

instance FromConf [String] where
    fromConf :: ConfValue -> [String]
fromConf (CV_String String
s)  = String -> String -> [String]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn String
"," String
s
    fromConf ConfValue
_ = String -> [String]
forall a. HasCallStack => String -> a
error String
"fromConf string"

----------------------------------------------------------------

parseConfig :: FilePath -> IO [Conf]
parseConfig :: String -> IO [Conf]
parseConfig = Parser [Conf] -> String -> IO [Conf]
forall a. Parser a -> String -> IO a
parseFile Parser [Conf]
config

----------------------------------------------------------------

config :: Parser [Conf]
config :: Parser [Conf]
config = Parser ()
commentLines Parser () -> Parser [Conf] -> Parser [Conf]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT ByteString () Identity Conf -> Parser [Conf]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT ByteString () Identity Conf
cfield Parser [Conf] -> Parser () -> Parser [Conf]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
  where
    cfield :: ParsecT ByteString () Identity Conf
cfield = ParsecT ByteString () Identity Conf
field ParsecT ByteString () Identity Conf
-> Parser () -> ParsecT ByteString () Identity Conf
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
commentLines

field :: Parser Conf
field :: ParsecT ByteString () Identity Conf
field = (,) (String -> ConfValue -> Conf)
-> ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity (ConfValue -> Conf)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT ByteString () Identity String
key ParsecT ByteString () Identity (ConfValue -> Conf)
-> ParsecT ByteString () Identity ConfValue
-> ParsecT ByteString () Identity Conf
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Parser ()
sep Parser ()
-> ParsecT ByteString () Identity ConfValue
-> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT ByteString () Identity ConfValue
value)

key :: Parser String
key :: ParsecT ByteString () Identity String
key = ParsecT ByteString () Identity Char
-> ParsecT ByteString () Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT ByteString () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf (String -> ParsecT ByteString () Identity Char)
-> String -> ParsecT ByteString () Identity Char
forall a b. (a -> b) -> a -> b
$ [Char
'a'..Char
'z'] String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char
'A'..Char
'Z'] String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char
'0'..Char
'9'] String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"_") ParsecT ByteString () Identity String
-> Parser () -> ParsecT ByteString () Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
spcs

sep :: Parser ()
sep :: Parser ()
sep = () () -> ParsecT ByteString () Identity Char -> Parser ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT ByteString () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
':' Parser () -> Parser () -> Parser ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ()
spcs

value :: Parser ConfValue
value :: ParsecT ByteString () Identity ConfValue
value = [ParsecT ByteString () Identity ConfValue]
-> ParsecT ByteString () Identity ConfValue
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ParsecT ByteString () Identity ConfValue
-> ParsecT ByteString () Identity ConfValue
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT ByteString () Identity ConfValue
cv_natural, ParsecT ByteString () Identity ConfValue
-> ParsecT ByteString () Identity ConfValue
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT ByteString () Identity ConfValue
cv_bool, ParsecT ByteString () Identity ConfValue
cv_string]

-- Trailing should be included in try to allow IP addresses.
cv_natural :: Parser ConfValue
cv_natural :: ParsecT ByteString () Identity ConfValue
cv_natural = Natural -> ConfValue
CV_Natural (Natural -> ConfValue)
-> (String -> Natural) -> String -> ConfValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Natural
forall a. Read a => String -> a
read (String -> ConfValue)
-> ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT ByteString () Identity Char
-> ParsecT ByteString () Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT ByteString () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit ParsecT ByteString () Identity ConfValue
-> Parser () -> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
trailing

cv_bool :: Parser ConfValue
cv_bool :: ParsecT ByteString () Identity ConfValue
cv_bool = Bool -> ConfValue
CV_Bool Bool
True  ConfValue
-> ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> ParsecT ByteString () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"Yes" ParsecT ByteString () Identity ConfValue
-> Parser () -> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
trailing ParsecT ByteString () Identity ConfValue
-> ParsecT ByteString () Identity ConfValue
-> ParsecT ByteString () Identity ConfValue
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
          Bool -> ConfValue
CV_Bool Bool
False ConfValue
-> ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> ParsecT ByteString () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"No"  ParsecT ByteString () Identity ConfValue
-> Parser () -> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
trailing

cv_string :: Parser ConfValue
cv_string :: ParsecT ByteString () Identity ConfValue
cv_string = String -> ConfValue
CV_String (String -> ConfValue)
-> ParsecT ByteString () Identity String
-> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT ByteString () Identity Char
-> ParsecT ByteString () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> ParsecT ByteString () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
" \t\n") ParsecT ByteString () Identity ConfValue
-> Parser () -> ParsecT ByteString () Identity ConfValue
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
trailing