module Test.CliParser where

import Control.Applicative (optional, some, (*>), (<*), (<|>))
import Data.Attoparsec.Text (Parser, (<?>))
import qualified Data.Attoparsec.Text as Attoparsec
import Data.Functor (void)
import NriPrelude
import qualified Result
import qualified Test.Internal as Internal
import qualified Text
import qualified Prelude

parseArgs :: List Prelude.String -> Result Prelude.String Internal.Request
parseArgs :: List String -> Result String Request
parseArgs List String
args =
  case List String
args of
    [] -> Request -> Result String Request
forall error value. value -> Result error value
Ok Request
Internal.All
    [String
"--files"] -> String -> Result String Request
forall error value. error -> Result error value
Err String
"must inform at least one file: not enough input"
    [String
"--files", String
files] ->
      String -> Result String (List SubsetOfTests)
parse String
files
        Result String (List SubsetOfTests)
-> (Result String (List SubsetOfTests) -> Result String Request)
-> Result String Request
forall a b. a -> (a -> b) -> b
|> (List SubsetOfTests -> Result String Request)
-> Result String (List SubsetOfTests) -> Result String Request
forall a c b. (a -> Result c b) -> Result c a -> Result c b
Result.andThen
          ( \List SubsetOfTests
lists -> case List SubsetOfTests
lists of
              [] -> String -> Result String Request
forall error value. error -> Result error value
Err String
"must inform at least one file: not enough input"
              List SubsetOfTests
subsetOfTests -> Request -> Result String Request
forall error value. value -> Result error value
Ok (List SubsetOfTests -> Request
Internal.Some List SubsetOfTests
subsetOfTests)
          )
    String
_ : List String
rest -> List String -> Result String Request
parseArgs List String
rest

parse :: Prelude.String -> Result Prelude.String (List Internal.SubsetOfTests)
parse :: String -> Result String (List SubsetOfTests)
parse String
input =
  String
input
    String -> (String -> Text) -> Text
forall a b. a -> (a -> b) -> b
|> String -> Text
Text.fromList
    Text
-> (Text -> Either String (List SubsetOfTests))
-> Either String (List SubsetOfTests)
forall a b. a -> (a -> b) -> b
|> Parser (List SubsetOfTests)
-> Text -> Either String (List SubsetOfTests)
forall a. Parser a -> Text -> Either String a
Attoparsec.parseOnly (Parser (List SubsetOfTests)
argParser Parser (List SubsetOfTests)
-> Parser Text () -> Parser (List SubsetOfTests)
forall a b. Parser Text a -> Parser Text b -> Parser Text a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
endParser)
    Either String (List SubsetOfTests)
-> (Either String (List SubsetOfTests)
    -> Result String (List SubsetOfTests))
-> Result String (List SubsetOfTests)
forall a b. a -> (a -> b) -> b
|> (String -> Result String (List SubsetOfTests))
-> (List SubsetOfTests -> Result String (List SubsetOfTests))
-> Either String (List SubsetOfTests)
-> Result String (List SubsetOfTests)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
Prelude.either String -> Result String (List SubsetOfTests)
forall error value. error -> Result error value
Err List SubsetOfTests -> Result String (List SubsetOfTests)
forall error value. value -> Result error value
Ok

endParser :: Parser ()
endParser :: Parser Text ()
endParser = Parser Text ()
forall t. Chunk t => Parser t ()
Attoparsec.endOfInput Parser Text () -> Parser Text () -> Parser Text ()
forall a. Parser Text a -> Parser Text a -> Parser Text a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text Char -> Parser Text ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Char -> Parser Text Char
Attoparsec.char Char
',') Parser Text () -> Parser Text () -> Parser Text ()
forall a. Parser Text a -> Parser Text a -> Parser Text a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text ()
forall a. Parser a
unexpectedInput

argParser :: Parser (List Internal.SubsetOfTests)
argParser :: Parser (List SubsetOfTests)
argParser = Parser Text SubsetOfTests
-> Parser Text Char -> Parser (List SubsetOfTests)
forall (m :: * -> *) a s. MonadPlus m => m a -> m s -> m [a]
Attoparsec.sepBy1' (Parser Text SubsetOfTests
fileParser Parser Text SubsetOfTests
-> Parser Text SubsetOfTests -> Parser Text SubsetOfTests
forall a. Parser Text a -> Parser Text a -> Parser Text a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text SubsetOfTests
forall a. Parser a
unexpectedInput) (Char -> Parser Text Char
Attoparsec.char Char
',') Parser (List SubsetOfTests)
-> String -> Parser (List SubsetOfTests)
forall i a. Parser i a -> String -> Parser i a
<?> String
"must inform at least one file"

fileParser :: Parser Internal.SubsetOfTests
fileParser :: Parser Text SubsetOfTests
fileParser = do
  requestedPath <- Parser Text Char -> Parser Text String
forall a. Parser Text a -> Parser Text [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some ((Char -> Bool) -> Parser Text Char
Attoparsec.satisfy (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
':' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
','))
  lineOfCode <- optional (Attoparsec.char ':' *> Attoparsec.decimal)
  Prelude.pure Internal.SubsetOfTests {Internal.requestedPath, Internal.lineOfCode}

unexpectedInput :: Parser a
unexpectedInput :: forall a. Parser a
unexpectedInput = do
  rest <- Parser Text Char -> Parser Text String
forall a. Parser Text a -> Parser Text [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some Parser Text Char
Attoparsec.anyChar
  Prelude.fail ("expected format: --files=bla.hs or --files bla.hs: \"" ++ rest ++ "\"")