haskell-awk-1.2: runtime/System/Console/Hawk/Args/Spec.hs
{-# LANGUAGE LambdaCase, OverloadedStrings #-}
-- | The precisely-typed version of Hawk's command-line arguments.
module System.Console.Hawk.Args.Spec where
import Data.ByteString (ByteString)
data HawkSpec
= Help
| Version
| Eval ExprSpec OutputSpec
| Apply ExprSpec InputSpec OutputSpec
| Map ExprSpec InputSpec OutputSpec
deriving (Show, Eq)
data InputSpec = InputSpec
{ inputSource :: InputSource
, inputFormat :: InputFormat
}
deriving (Show, Eq)
data OutputSpec = OutputSpec
{ outputSink :: OutputSink
, outputFormat :: OutputFormat
}
deriving (Show, Eq)
data InputSource
= NoInput
| UseStdin
| InputFile FilePath
deriving (Show, Eq)
data OutputSink
= UseStdout
-- OutputFile FilePath -- we might want to implement --in-place
-- in the future
deriving (Show, Eq)
data InputFormat
= RawStream
| Records Separator RecordFormat
deriving (Show, Eq)
data RecordFormat
= RawRecord
| Fields Separator
deriving (Show, Eq)
-- We can't know ahead of time whether it's going to be a raw stream
-- or raw records or fields, it depends on the type of the user expression.
data OutputFormat = OutputFormat
{ recordDelimiter :: Delimiter
, fieldDelimiter :: Delimiter
}
deriving (Show, Eq)
-- A 'Processor' describes how to process a string; either by separating it
-- into chunks or by leaving it as-is. When separating it into chunks, we can
-- use whitespace as a delimiter (meaning one or more consecutive whitespace
-- characters), or we can use a specific delimiter.
type Delimiter = ByteString
data Separator = Whitespace | Delimiter Delimiter
deriving (Show, Eq)
data Processor = DoNotSeparate | SeparateOn Separator
deriving (Show, Eq)
fromSeparator :: Delimiter -> Separator -> Delimiter
fromSeparator def = \case
Whitespace -> def
Delimiter d -> d
fromProcessor :: Delimiter -> Processor -> Delimiter
fromProcessor def = \case
DoNotSeparate -> def
SeparateOn s -> fromSeparator def s
newtype ContextSpec = ContextSpec
{ userContextDirectory :: FilePath
}
deriving (Show, Eq)
type UntypedExpr = String
data ExprSpec = ExprSpec
{ contextSpec :: ContextSpec
, untypedExpr :: UntypedExpr
}
deriving (Show, Eq)
defaultInputSpec, noInput :: InputSpec
defaultInputSpec = InputSpec UseStdin defaultInputFormat
noInput = InputSpec NoInput defaultInputFormat
defaultOutputSpec :: OutputSpec
defaultOutputSpec = OutputSpec UseStdout defaultOutputFormat
defaultInputFormat :: InputFormat
defaultInputFormat = Records defaultRecordSeparator
$ Fields defaultFieldSeparator
defaultOutputFormat :: OutputFormat
defaultOutputFormat = OutputFormat defaultRecordDelimiter defaultFieldDelimiter
defaultRecordSeparator, defaultFieldSeparator :: Separator
defaultRecordSeparator = Delimiter defaultRecordDelimiter
defaultFieldSeparator = Whitespace
defaultRecordDelimiter, defaultFieldDelimiter :: Delimiter
defaultRecordDelimiter = "\n"
defaultFieldDelimiter = " "