module Attoparsec.Data.Explicit
  ( char,
    text,
    utf8Bytes,
    bool,
    signedIntegral,
    unsignedIntegral,
    A.double,
    A.scientific,
    string,
    uuid,
    D.show,

    -- * Time
    B.timeOfDayInISO8601,
    B.dayInISO8601,
    B.timeZoneInISO8601,
    B.utcTimeInISO8601,
    B.diffTime,
    B.nominalDiffTime,
  )
where

import qualified Attoparsec.Data.Parsers as D
import Attoparsec.Data.Prelude hiding (bool)
import qualified Attoparsec.Time.Text as B
import qualified Data.Attoparsec.Text as A
import qualified Data.Text.Encoding as C
import qualified Data.UUID as Uuid

-- |
-- Any character.
char :: A.Parser Char
char :: Parser Char
char =
  Parser Char
A.anyChar

-- |
-- Consumes all the remaining input.
text :: A.Parser Text
text :: Parser Text
text =
  Parser Text
A.takeText

-- |
-- Consumes all the remaining input, encoding it using UTF8.
utf8Bytes :: A.Parser ByteString
utf8Bytes :: Parser ByteString
utf8Bytes =
  Text -> ByteString
C.encodeUtf8 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
A.takeText

-- |
-- Accepts any string interpretable as a boolean:
-- "1" or "0", "true" or "false", "yes" or "no", "y" or "n", "t" or "f".
-- Case-insensitive.
bool :: A.Parser Bool
bool :: Parser Bool
bool =
  Parser Char
A.anyChar forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Char
'0' -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
    Char
'1' -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
    Char
'f' -> Text -> Parser Text
A.asciiCI Text
"alse" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
False forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
    Char
'F' -> Text -> Parser Text
A.asciiCI Text
"alse" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
False forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
    Char
't' -> Text -> Parser Text
A.asciiCI Text
"rue" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
    Char
'T' -> Text -> Parser Text
A.asciiCI Text
"rue" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
    Char
'n' -> (Char -> Bool) -> Parser Char
A.satisfy (String -> Char -> Bool
A.inClass String
"oO") forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
False forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
    Char
'N' -> (Char -> Bool) -> Parser Char
A.satisfy (String -> Char -> Bool
A.inClass String
"oO") forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
False forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
    Char
'y' -> Text -> Parser Text
A.asciiCI Text
"es" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
    Char
'Y' -> Text -> Parser Text
A.asciiCI Text
"es" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
    Char
_ -> forall (f :: * -> *) a. Alternative f => f a
empty

-- |
-- Signed decimal.
signedIntegral :: (Integral a) => A.Parser a
signedIntegral :: forall a. Integral a => Parser a
signedIntegral =
  forall a. Num a => Parser a -> Parser a
A.signed forall a. Integral a => Parser a
A.decimal

-- |
-- Unsigned decimal.
unsignedIntegral :: (Integral a) => A.Parser a
unsignedIntegral :: forall a. Integral a => Parser a
unsignedIntegral =
  forall a. Integral a => Parser a
A.decimal

-- |
-- Plain String.
string :: A.Parser String
string :: Parser String
string =
  forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser Char
A.anyChar

-- |
-- UUID.
uuid :: A.Parser UUID
uuid :: Parser UUID
uuid = do
  Text
text <- Int -> Parser Text
A.take Int
36
  case Text -> Maybe UUID
Uuid.fromText Text
text of
    Just UUID
uuid -> forall (m :: * -> *) a. Monad m => a -> m a
return UUID
uuid
    Maybe UUID
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> ShowS
showString String
"Unparsable UUID: " (forall a. Show a => a -> String
show Text
text))