R56UG3O4Q6I3VWL3AAFCBPELK4HQPSGKBEZZZR2IN6OEBCT6SZCAC R3FT6FQUBETBTUO3IV5VWORIULZ4JR23YEF5NYWWSNDP7NYWVGYQC OPVRIDNC3QFQEPSXINRLSV3GWUPGTW6YVQV6BEDS6BP2CAUWIIXAC R3GV7TM2HTCXTHWA76FZK6JJRSXCPRPXHV7FKMWXPQ2W2RIOTXEQC B2JWXIEPCMVVITDJDR2SACY4VHITXGH7ZM6A5RWN6E7OKTO43TUAC PQ2LKDLRPPS3JQBREYZRBUJ7DSU2TNWGJ6CKRXNZAUZF42IVMQRAC LHB2J7Q7QZPVLC6EAZPB3MRVNMIWPCUXEJ55NUOOM3NCCRXLNOLQC 3BPYUTTBYTGGEI7NI3YJLDGR7XSMQTB7IKXBXDJLN7U6Q5XZP63AC import Data.Attoparsec.Text (anyChar, endOfInput, parseOnly)import qualified Data.Attoparsec.Text as Attoimport Data.Bifunctor (bimap, first)import Data.Either.Extraimport qualified Data.Text as Text
import Options.Primer (PrimerCommand)import qualified Options.Primer as PrimerOptions
import Control.Monadimport Text.Read (readEither)import AlBhed (Primer, Volume)import qualified AlBhedimport Location (Location)import qualified Locationimport Data.PrintableText (PrintableText)import qualified Data.PrintableText as PrintableText
commandPrimer :: Parser PrimerCommandcommandPrimer = hsubparser( command "add" (info parsePrimerAdd (progDesc "Add a primer location to the index"))<> command "new" (info parsePrimerNew (progDesc "Add a new AlBhed Primer to the index"))<> command "ls" (info (pure List) (progDesc "List all AlBhed Primers in the index")))parsePrimerNew :: Parser PrimerCommandparsePrimerNew = New <$> volume <*> char "FROM" <*> char "TO" <*> locationwherechar = argument singleChar . metavarsingleChar :: ReadM CharsingleChar = eitherReader $first parseError . (parseOnly oneChar . Text.pack)whereparseError = const "Expecting a single character"oneChar = anyChar <* endOfInputparsePrimerAdd :: Parser PrimerCommandparsePrimerAdd = Add <$> volume <*> locationvolume :: Parser Volumevolume = argument parseVolume (metavar "VOLUME")location :: Parser Locationlocation = Location.Location<$> argument parsePrintableText (metavar "AREA")<*> optional (argument parsePrintableText (metavar "SECTION"))parseVolume :: ReadM VolumeparseVolume = eitherReader $(first parseError . input) >=> volumewhereparseError = const "Failed to parse volume number"input = readEither @Intvolume = maybeToEither "Volume must be 1 to 26" . AlBhed.toVolumeparsePrintableText :: ReadM PrintableTextparsePrintableText = eitherReader $input >=> locationwhereinput = Rightlocation = maybeToEither "Location can't contain only whitespace" . PrintableText.fromText . Text.pack
{-# LANGUAGE TypeApplications #-}module Options.Primer( PrimerCommand (..), commands) whereimport Options.Applicativeimport qualified Options.Parsers as Parserimport Data.Bifunctor (bimap, first)import Data.Either.Extra (maybeToEither)import Control.Monadimport Text.Read (readEither)import AlBhed (Primer, Volume)import qualified AlBhedimport Location (Location)import qualified Locationdata PrimerCommand =Add Volume Location| New Volume Char Char Location| Listderiving (Show)commands :: Parser PrimerCommandcommands = hsubparser( command "add" (info addCommand (progDesc "Add a primer location to the index"))<> command "new" (info newCommand (progDesc "Add a new AlBhed Primer to the index"))<> command "ls" (info (pure List) (progDesc "List all AlBhed Primers in the index")))newCommand :: Parser PrimerCommandnewCommand = New <$> volume <*> char "FROM" <*> char "TO" <*> locationwherechar = argument Parser.singleChar . metavaraddCommand :: Parser PrimerCommandaddCommand = Add <$> volume <*> locationvolume :: Parser Volumevolume = argument parseVolume (metavar "VOLUME")location :: Parser Locationlocation = Location.Location<$> argument Parser.printableText (metavar "AREA")<*> optional (argument Parser.printableText (metavar "SECTION"))parseVolume :: ReadM VolumeparseVolume = eitherReader $(first parseError . input) >=> volumewhereparseError = const "Failed to parse volume number"input = readEither @Intvolume = maybeToEither "Volume must be 1 to 26" . AlBhed.toVolume
module Options.Parsers( printableText, singleChar) whereimport Options.Applicativeimport Data.Attoparsec.Text (anyChar, endOfInput, parseOnly)import qualified Data.Attoparsec.Text as Attoimport Data.Bifunctor (bimap, first)import Data.Either.Extra (maybeToEither)import qualified Data.Text as Textimport Control.Monadimport Data.PrintableText (PrintableText)import qualified Data.PrintableText as PrintableTextsingleChar :: ReadM CharsingleChar = eitherReader $first parseError . (parseOnly oneChar . Text.pack)whereparseError = const "Expecting a single character"oneChar = anyChar <* endOfInputprintableText :: ReadM PrintableTextprintableText = eitherReader $input >=> locationwhereinput = Rightlocation = maybeToEither "Location can't contain only whitespace" . PrintableText.fromText . Text.pack