vfr-waypoints-0.1.0.1: src/executable/Main.hs
{-# LANGUAGE NoImplicitPrelude #-}
module Main(
main
) where
import Control.Applicative(pure, (<*>), (<**>))
import Control.Category((.))
import Data.Aviation.VFR_Waypoints.Render(renderVFR_Waypoint, render0ResultsOr, render0ResultsList, renderVFR_WaypointHeader, runColour)
import Data.Aviation.VFR_Waypoints.Search(searchIndexCode, searchIndexName, searchIndexCodeName, searchFuzzyCode, searchFuzzyName, searchFuzzyCodeName)
import Data.Bool(Bool(True, False), not)
import Data.Eq(Eq)
import Data.Function(($))
import Data.Functor((<$>), fmap)
import Data.Int(Int)
import Data.List(filter, (++))
import Data.Maybe(Maybe(Nothing, Just))
import Data.Ord(Ord((>=)))
import Data.Semigroup((<>))
import Data.String(String)
import Options.Applicative(Parser, execParser, info, helper, fullDesc, header, option, maybeReader, short, long, value, metavar, help, switch, strOption)
import Prelude(Show(show))
import System.IO(IO, putStrLn)
import Text.Fuzzy(Fuzzy(Fuzzy))
import Text.Read(reads)
main ::
IO ()
main =
let opts =
execParser
(info (parserOptions <**> helper) (
fullDesc <>
header "vfr-waypoints for searching VFR waypoints"
)
)
in do Options c h m t x <- opts
let output h' =
case t of
Exact ->
let k =
case m of
Code ->
searchIndexCode
Name ->
searchIndexName
Both ->
searchIndexCodeName
render w =
renderVFR_Waypoint (w, "-")
in render0ResultsOr h'
(render <$> k x)
Inexact sc ->
let k =
case m of
Code ->
searchFuzzyCode
Name ->
searchFuzzyName
Both ->
searchFuzzyCodeName
render (Fuzzy o _ s) =
renderVFR_Waypoint (o, show s)
scores (Fuzzy _ _ s) =
case sc of
Nothing ->
True
Just sc' ->
s >= sc'
in render0ResultsList h'
(
fmap render .
filter scores $
(k x "" "" False)
)
decideheader2 =
if h
then
pure ""
else
(++ "\n") <$> renderVFR_WaypointHeader
alloutput =
output decideheader2
putStrLn (runColour alloutput (not c))
data MatchOptions =
Code
| Name
| Both
deriving (Eq, Ord, Show)
parserMatchOptions ::
Parser MatchOptions
parserMatchOptions =
option
(maybeReader (\s -> case s of
"code" ->
Just Code
"name" ->
Just Name
"both" ->
Just Both
_ ->
Nothing))
(
short 'm' <>
long "match" <>
value Both <>
metavar "(code|name|both)" <>
help "Search on VFR waypoint code, name or both code and name"
)
data MatchType =
Exact
| Inexact (Maybe Int)
deriving (Eq, Ord, Show)
parserMatchType ::
Parser MatchType
parserMatchType =
let opts exact minscore =
if exact
then
Exact
else
Inexact minscore
in opts <$>
switch
(
short 'e' <>
long "exact" <>
help "match the search term exactly"
) <*>
option
(
maybeReader
(\s -> case reads s of
(n, _):_ ->
Just (Just n)
[] ->
Nothing)
)
(
short 's' <>
long "min-score" <>
value Nothing <>
help "minimum fuzzy match score"
)
data Options =
Options
Bool -- colours
Bool -- header
MatchOptions
MatchType
String
deriving (Eq, Ord, Show)
parserOptions ::
Parser Options
parserOptions =
Options <$>
switch
(
short 'r' <>
long "colour" <>
help "turn off colouring with ANSI escape code"
) <*>
switch
(
short 'h' <>
long "header" <>
help "turn off header in search results"
) <*>
parserMatchOptions <*>
parserMatchType <*>
strOption
(
short 't' <>
long "term" <>
help "the search term"
)