module Data.Parser.CacheControl
( CacheControl,
CacheControlDirective (..),
parseCacheControl,
parseMaxAge,
findMaxAge,
noCacheExists,
noStoreExists,
mustRevalidateExists,
)
where
import Data.Attoparsec.Text qualified as AT
import Data.Text qualified as T
import Hasura.Prelude
import Hasura.Server.Utils (fmapL)
type CacheControl = [CacheControlDirective]
data CacheControlDirective
= CCDOnlyToken !Text
| CCDTokenWithVal !Text !Text
deriving (Int -> CacheControlDirective -> ShowS
[CacheControlDirective] -> ShowS
CacheControlDirective -> String
(Int -> CacheControlDirective -> ShowS)
-> (CacheControlDirective -> String)
-> ([CacheControlDirective] -> ShowS)
-> Show CacheControlDirective
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CacheControlDirective] -> ShowS
$cshowList :: [CacheControlDirective] -> ShowS
show :: CacheControlDirective -> String
$cshow :: CacheControlDirective -> String
showsPrec :: Int -> CacheControlDirective -> ShowS
$cshowsPrec :: Int -> CacheControlDirective -> ShowS
Show, CacheControlDirective -> CacheControlDirective -> Bool
(CacheControlDirective -> CacheControlDirective -> Bool)
-> (CacheControlDirective -> CacheControlDirective -> Bool)
-> Eq CacheControlDirective
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CacheControlDirective -> CacheControlDirective -> Bool
$c/= :: CacheControlDirective -> CacheControlDirective -> Bool
== :: CacheControlDirective -> CacheControlDirective -> Bool
$c== :: CacheControlDirective -> CacheControlDirective -> Bool
Eq)
parseMaxAge :: Integral a => Text -> Either String a
parseMaxAge :: Text -> Either String a
parseMaxAge Text
t =
Text -> Either String [CacheControlDirective]
parseCacheControl Text
t Either String [CacheControlDirective]
-> ([CacheControlDirective] -> Either String (Maybe a))
-> Either String (Maybe a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [CacheControlDirective] -> Either String (Maybe a)
forall a.
Integral a =>
[CacheControlDirective] -> Either String (Maybe a)
findMaxAge Either String (Maybe a)
-> (Maybe a -> Either String a) -> Either String a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either String a
-> (a -> Either String a) -> Maybe a -> Either String a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Either String a
forall a b. a -> Either a b
Left String
notFoundErr) a -> Either String a
forall a b. b -> Either a b
Right
where
notFoundErr :: String
notFoundErr = String
"could not find max-age/s-maxage"
findMaxAge :: Integral a => CacheControl -> Either String (Maybe a)
findMaxAge :: [CacheControlDirective] -> Either String (Maybe a)
findMaxAge [CacheControlDirective]
cacheControl = do
case (Text -> Bool) -> [CacheControlDirective] -> Maybe (Text, Text)
findCCDTokenWithVal Text -> Bool
forall a. (Eq a, IsString a) => a -> Bool
checkMaxAgeToken [CacheControlDirective]
cacheControl of
Just (Text
_, Text
val) -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> Either String a -> Either String (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ShowS -> Either String a -> Either String a
forall a a' b. (a -> a') -> Either a b -> Either a' b
fmapL ShowS
forall p p. IsString p => p -> p
parseErr (Parser a -> Text -> Either String a
forall a. Parser a -> Text -> Either String a
AT.parseOnly Parser a
forall a. Integral a => Parser a
AT.decimal Text
val)
Maybe (Text, Text)
Nothing -> Maybe a -> Either String (Maybe a)
forall a b. b -> Either a b
Right Maybe a
forall a. Maybe a
Nothing
where
parseErr :: p -> p
parseErr p
_ = p
"could not parse max-age/s-maxage value"
checkMaxAgeToken :: a -> Bool
checkMaxAgeToken a
token = a
token a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"max-age" Bool -> Bool -> Bool
|| a
token a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"s-maxage"
noCacheExists :: CacheControl -> Bool
noCacheExists :: [CacheControlDirective] -> Bool
noCacheExists [CacheControlDirective]
cacheControl =
Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool) -> Maybe Text -> Bool
forall a b. (a -> b) -> a -> b
$ (Text -> Bool) -> [CacheControlDirective] -> Maybe Text
findCCDOnlyToken (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"no-cache") [CacheControlDirective]
cacheControl
noStoreExists :: CacheControl -> Bool
noStoreExists :: [CacheControlDirective] -> Bool
noStoreExists [CacheControlDirective]
cacheControl =
Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool) -> Maybe Text -> Bool
forall a b. (a -> b) -> a -> b
$ (Text -> Bool) -> [CacheControlDirective] -> Maybe Text
findCCDOnlyToken (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"no-store") [CacheControlDirective]
cacheControl
mustRevalidateExists :: CacheControl -> Bool
mustRevalidateExists :: [CacheControlDirective] -> Bool
mustRevalidateExists [CacheControlDirective]
cacheControl =
Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool) -> Maybe Text -> Bool
forall a b. (a -> b) -> a -> b
$ (Text -> Bool) -> [CacheControlDirective] -> Maybe Text
findCCDOnlyToken (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"must-revalidate") [CacheControlDirective]
cacheControl
findCCDOnlyToken :: (Text -> Bool) -> CacheControl -> Maybe Text
findCCDOnlyToken :: (Text -> Bool) -> [CacheControlDirective] -> Maybe Text
findCCDOnlyToken Text -> Bool
tokenPredicate [CacheControlDirective]
cacheControl =
[Text] -> Maybe Text
forall a. [a] -> Maybe a
listToMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$ (CacheControlDirective -> Maybe Text)
-> [CacheControlDirective] -> [Text]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe CacheControlDirective -> Maybe Text
check [CacheControlDirective]
cacheControl
where
check :: CacheControlDirective -> Maybe Text
check = \case
CCDOnlyToken Text
token
| Text -> Bool
tokenPredicate Text
token -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
token
| Bool
otherwise -> Maybe Text
forall a. Maybe a
Nothing
CCDTokenWithVal Text
_ Text
_ -> Maybe Text
forall a. Maybe a
Nothing
findCCDTokenWithVal :: (Text -> Bool) -> CacheControl -> Maybe (Text, Text)
findCCDTokenWithVal :: (Text -> Bool) -> [CacheControlDirective] -> Maybe (Text, Text)
findCCDTokenWithVal Text -> Bool
tokenPredicate [CacheControlDirective]
cacheControl =
[(Text, Text)] -> Maybe (Text, Text)
forall a. [a] -> Maybe a
listToMaybe ([(Text, Text)] -> Maybe (Text, Text))
-> [(Text, Text)] -> Maybe (Text, Text)
forall a b. (a -> b) -> a -> b
$ (CacheControlDirective -> Maybe (Text, Text))
-> [CacheControlDirective] -> [(Text, Text)]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe CacheControlDirective -> Maybe (Text, Text)
check [CacheControlDirective]
cacheControl
where
check :: CacheControlDirective -> Maybe (Text, Text)
check = \case
CCDOnlyToken Text
_ -> Maybe (Text, Text)
forall a. Maybe a
Nothing
CCDTokenWithVal Text
token Text
value
| Text -> Bool
tokenPredicate Text
token -> (Text, Text) -> Maybe (Text, Text)
forall a. a -> Maybe a
Just (Text
token, Text
value)
| Bool
otherwise -> Maybe (Text, Text)
forall a. Maybe a
Nothing
parseCacheControl :: Text -> Either String CacheControl
parseCacheControl :: Text -> Either String [CacheControlDirective]
parseCacheControl = Parser [CacheControlDirective]
-> Text -> Either String [CacheControlDirective]
forall a. Parser a -> Text -> Either String a
AT.parseOnly Parser [CacheControlDirective]
cacheControlParser
cacheControlParser :: AT.Parser CacheControl
cacheControlParser :: Parser [CacheControlDirective]
cacheControlParser = do
Parser Text [Maybe Char] -> Parser Text ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser Text [Maybe Char] -> Parser Text ())
-> Parser Text [Maybe Char] -> Parser Text ()
forall a b. (a -> b) -> a -> b
$ Parser Text (Maybe Char) -> Parser Text [Maybe Char]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
AT.many' (Parser Text Text
"," Parser Text Text
-> Parser Text (Maybe Char) -> Parser Text (Maybe Char)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Text (Maybe Char)
optionalWhitespaceParser)
CacheControlDirective
cd <- Parser CacheControlDirective
cacheDirectiveParser
[Maybe CacheControlDirective]
cds <- Parser Text (Maybe CacheControlDirective)
-> Parser Text [Maybe CacheControlDirective]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
AT.many' (Parser Text (Maybe CacheControlDirective)
-> Parser Text [Maybe CacheControlDirective])
-> Parser Text (Maybe CacheControlDirective)
-> Parser Text [Maybe CacheControlDirective]
forall a b. (a -> b) -> a -> b
$ Parser Text (Maybe Char)
optionalWhitespaceParser Parser Text (Maybe Char) -> Parser Text Text -> Parser Text Text
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Text Text
"," Parser Text Text
-> Parser Text (Maybe CacheControlDirective)
-> Parser Text (Maybe CacheControlDirective)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Maybe CacheControlDirective
-> Parser Text (Maybe CacheControlDirective)
-> Parser Text (Maybe CacheControlDirective)
forall (f :: * -> *) a. Alternative f => a -> f a -> f a
AT.option Maybe CacheControlDirective
forall a. Maybe a
Nothing (CacheControlDirective -> Maybe CacheControlDirective
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CacheControlDirective -> Maybe CacheControlDirective)
-> Parser CacheControlDirective
-> Parser Text (Maybe CacheControlDirective)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser CacheControlDirective
optionalDirective)
[CacheControlDirective] -> Parser [CacheControlDirective]
forall (m :: * -> *) a. Monad m => a -> m a
return ([CacheControlDirective] -> Parser [CacheControlDirective])
-> [CacheControlDirective] -> Parser [CacheControlDirective]
forall a b. (a -> b) -> a -> b
$ CacheControlDirective
cd CacheControlDirective
-> [CacheControlDirective] -> [CacheControlDirective]
forall a. a -> [a] -> [a]
: [Maybe CacheControlDirective] -> [CacheControlDirective]
forall (f :: * -> *) a. Filterable f => f (Maybe a) -> f a
catMaybes [Maybe CacheControlDirective]
cds
where
optionalDirective :: Parser CacheControlDirective
optionalDirective = Parser Text (Maybe Char)
optionalWhitespaceParser Parser Text (Maybe Char)
-> Parser CacheControlDirective -> Parser CacheControlDirective
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser CacheControlDirective
cacheDirectiveParser
optionalWhitespaceParser :: AT.Parser (Maybe Char)
optionalWhitespaceParser :: Parser Text (Maybe Char)
optionalWhitespaceParser = Maybe Char -> Parser Text (Maybe Char) -> Parser Text (Maybe Char)
forall (f :: * -> *) a. Alternative f => a -> f a -> f a
AT.option Maybe Char
forall a. Maybe a
Nothing (Char -> Maybe Char
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Char -> Maybe Char)
-> Parser Text Char -> Parser Text (Maybe Char)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text Char
AT.space)
cacheDirectiveParser :: AT.Parser CacheControlDirective
cacheDirectiveParser :: Parser CacheControlDirective
cacheDirectiveParser = Parser CacheControlDirective
tokenWithValue Parser CacheControlDirective
-> Parser CacheControlDirective -> Parser CacheControlDirective
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser CacheControlDirective
onlyToken
where
onlyToken :: Parser CacheControlDirective
onlyToken = Text -> CacheControlDirective
CCDOnlyToken (Text -> CacheControlDirective)
-> Parser Text Text -> Parser CacheControlDirective
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text Text
tokenParser
tokenWithValue :: Parser CacheControlDirective
tokenWithValue = do
Text
tok <- Parser Text Text
tokenParser
Parser Text Char -> Parser Text ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser Text Char -> Parser Text ())
-> Parser Text Char -> Parser Text ()
forall a b. (a -> b) -> a -> b
$ Char -> Parser Text Char
AT.char Char
'='
Text
val <- Parser Text Text
tokenParser Parser Text Text -> Parser Text Text -> Parser Text Text
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text Text
quotedStringParser
CacheControlDirective -> Parser CacheControlDirective
forall (m :: * -> *) a. Monad m => a -> m a
return (CacheControlDirective -> Parser CacheControlDirective)
-> CacheControlDirective -> Parser CacheControlDirective
forall a b. (a -> b) -> a -> b
$ Text -> Text -> CacheControlDirective
CCDTokenWithVal Text
tok Text
val
tokenParser :: AT.Parser Text
tokenParser :: Parser Text Text
tokenParser = String -> Text
T.pack (String -> Text) -> Parser Text String -> Parser Text Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text Char -> Parser Text String
forall (f :: * -> *) a. Alternative f => f a -> f [a]
AT.many1 Parser Text Char
tcharParser
tcharParser :: AT.Parser Char
tcharParser :: Parser Text Char
tcharParser =
Char -> Parser Text Char
AT.char Char
'!'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'#'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'$'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'%'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'&'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'\''
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'*'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'+'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'-'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'.'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'^'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'_'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'`'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'|'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'~'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text Char
AT.digit
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text Char
AT.letter
dquoteParser :: AT.Parser Char
dquoteParser :: Parser Text Char
dquoteParser = Char -> Parser Text Char
AT.char Char
'"'
vcharParser :: AT.Parser Char
vcharParser :: Parser Text Char
vcharParser = Parser Text Char
AT.anyChar
quotedStringParser :: AT.Parser Text
quotedStringParser :: Parser Text Text
quotedStringParser =
Parser Text Char
dquoteParser Parser Text Char -> Parser Text Text -> Parser Text Text
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (String -> Text) -> Parser Text String -> Parser Text Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Text
T.pack (Parser Text Char -> Parser Text String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
AT.many' (Parser Text Char
qdTextParser Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text Char
quotedPairParser)) Parser Text Text -> Parser Text Char -> Parser Text Text
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text Char
dquoteParser
quotedPairParser :: AT.Parser Char
quotedPairParser :: Parser Text Char
quotedPairParser =
Text -> Parser Text Text
AT.string Text
"\\" Parser Text Text -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser Text Char
AT.space Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text Char
vcharParser)
qdTextParser :: AT.Parser Char
qdTextParser :: Parser Text Char
qdTextParser =
Parser Text Char
AT.space
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'!'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'#'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'$'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'%'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'&'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'\''
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'('
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
')'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'*'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'+'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
','
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'-'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'.'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'/'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text Char
AT.digit
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
':'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
';'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'<'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'='
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'>'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'?'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'@'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text Char
AT.letter
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'['
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
']'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'^'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'_'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'`'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'{'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'|'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'}'
Parser Text Char -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> Parser Text Char
AT.char Char
'~'