{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Df1.Parse
( log
) where
import Control.Applicative ((<|>), many, empty)
import Data.Bits (shiftL)
import qualified Data.Sequence as Seq
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Data.Function (fix)
import Data.Functor (($>))
import qualified Data.Attoparsec.ByteString as AB
import qualified Data.Attoparsec.ByteString.Lazy as ABL
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TL
import qualified Data.Time as Time
import qualified Data.Time.Clock.System as Time
import Data.Word (Word8, Word16, Word32)
import Prelude hiding (log)
import Df1.Render ()
import Df1.Types
(Log(Log, log_time, log_level, log_path, log_message),
Level(Debug, Info, Notice, Warning, Error, Critical, Alert, Emergency),
Path(Attr, Push),
Segment, segment,
Key, key,
Value, value,
Message, message)
log :: AB.Parser Log
{-# INLINABLE log #-}
log :: Parser Log
log = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"log") forall a b. (a -> b) -> a -> b
$ do
UTCTime
t <- (Word8 -> Bool) -> Parser ()
AB.skipWhile (forall a. Eq a => a -> a -> Bool
== Word8
32) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString UTCTime
pIso8601
Seq Path
p <- (Word8 -> Bool) -> Parser ()
AB.skipWhile (forall a. Eq a => a -> a -> Bool
== Word8
32) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString (Seq Path)
pPath
Level
l <- (Word8 -> Bool) -> Parser ()
AB.skipWhile (forall a. Eq a => a -> a -> Bool
== Word8
32) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString Level
pLevel
Message
m <- (Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
32) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString Message
pMessage
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Log { log_time :: SystemTime
log_time = UTCTime -> SystemTime
Time.utcToSystemTime UTCTime
t
, log_level :: Level
log_level = Level
l, log_path :: Seq Path
log_path = Seq Path
p, log_message :: Message
log_message = Message
m })
pIso8601 :: AB.Parser Time.UTCTime
{-# INLINABLE pIso8601 #-}
pIso8601 :: Parser ByteString UTCTime
pIso8601 = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pIso8601") forall a b. (a -> b) -> a -> b
$ do
Word16
year <- (Parser ByteString Word16
pNum4Digits forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"year") forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
45) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"-")
Word8
month <- (Parser ByteString Word8
pNum2Digits forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"month") forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
45) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"-")
Word8
day <- (Parser ByteString Word8
pNum2Digits forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"day") forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
84) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"T")
Just Day
tday <- forall (f :: * -> *) a. Applicative f => a -> f a
pure (Year -> MonthOfYear -> MonthOfYear -> Maybe Day
Time.fromGregorianValid
(forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
year) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
month) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
day))
Word8
hour <- (Parser ByteString Word8
pNum2Digits forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"hour") forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
58) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
":")
Word8
min' <- (Parser ByteString Word8
pNum2Digits forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"minute") forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
58) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
":")
Word8
sec <- (Parser ByteString Word8
pNum2Digits forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"second") forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
46) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
".")
Word32
nsec <- (Parser ByteString Word32
pNum9Digits forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"nanosecond") forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
90) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"Z")
Just TimeOfDay
ttod <- forall (f :: * -> *) a. Applicative f => a -> f a
pure (MonthOfYear -> MonthOfYear -> Pico -> Maybe TimeOfDay
Time.makeTimeOfDayValid
(forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
hour) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
min')
(forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
sec forall a. Num a => a -> a -> a
+ (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
nsec forall a. Fractional a => a -> a -> a
/ Pico
1000000000)))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Day -> DiffTime -> UTCTime
Time.UTCTime Day
tday (TimeOfDay -> DiffTime
Time.timeOfDayToTime TimeOfDay
ttod))
pNum1Digit :: AB.Parser Word8
{-# INLINE pNum1Digit #-}
pNum1Digit :: Parser ByteString Word8
pNum1Digit = forall a. (Word8 -> a) -> (a -> Bool) -> Parser a
AB.satisfyWith (forall a. Num a => a -> a -> a
subtract Word8
48) (forall a. Ord a => a -> a -> Bool
< Word8
10) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum1Digit"
pNum2Digits :: AB.Parser Word8
{-# INLINE pNum2Digits #-}
pNum2Digits :: Parser ByteString Word8
pNum2Digits = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum2Digits") forall a b. (a -> b) -> a -> b
$ do
forall a. Num a => a -> a -> a
(+) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Num a => a -> a -> a
* Word8
10) Parser ByteString Word8
pNum1Digit forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString Word8
pNum1Digit
pNum4Digits :: AB.Parser Word16
{-# INLINE pNum4Digits #-}
pNum4Digits :: Parser ByteString Word16
pNum4Digits = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum4Digits") forall a b. (a -> b) -> a -> b
$ do
(\Word16
a Word16
b Word16
c Word16
d -> Word16
a forall a. Num a => a -> a -> a
+ Word16
b forall a. Num a => a -> a -> a
+ Word16
c forall a. Num a => a -> a -> a
+ Word16
d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word16
1000) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word16
100) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word16
10) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (Integral a, Num b) => a -> b
fromIntegral Parser ByteString Word8
pNum1Digit
pNum9Digits :: AB.Parser Word32
{-# INLINE pNum9Digits #-}
pNum9Digits :: Parser ByteString Word32
pNum9Digits = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum9Digits") forall a b. (a -> b) -> a -> b
$ do
(\Word32
a Word32
b Word32
c Word32
d Word32
e Word32
f Word32
g Word32
h Word32
i -> Word32
a forall a. Num a => a -> a -> a
+ Word32
b forall a. Num a => a -> a -> a
+ Word32
c forall a. Num a => a -> a -> a
+ Word32
d forall a. Num a => a -> a -> a
+ Word32
e forall a. Num a => a -> a -> a
+ Word32
f forall a. Num a => a -> a -> a
+ Word32
g forall a. Num a => a -> a -> a
+ Word32
h forall a. Num a => a -> a -> a
+ Word32
i)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word32
100000000) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word32
10000000) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word32
1000000) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word32
100000) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word32
10000) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word32
1000) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word32
100) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* Word32
10) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser ByteString Word8
pNum1Digit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (Integral a, Num b) => a -> b
fromIntegral Parser ByteString Word8
pNum1Digit
pLevel :: AB.Parser Level
{-# INLINE pLevel #-}
pLevel :: Parser ByteString Level
pLevel = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pLevel")
(ByteString -> Parser ByteString
AB.string ByteString
"INFO" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Info) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
(ByteString -> Parser ByteString
AB.string ByteString
"DEBUG" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Debug) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
(ByteString -> Parser ByteString
AB.string ByteString
"NOTICE" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Notice) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
(ByteString -> Parser ByteString
AB.string ByteString
"WARNING" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Warning) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
(ByteString -> Parser ByteString
AB.string ByteString
"ERROR" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Error) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
(ByteString -> Parser ByteString
AB.string ByteString
"CRITICAL" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Critical) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
(ByteString -> Parser ByteString
AB.string ByteString
"ALERT" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Alert) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
(ByteString -> Parser ByteString
AB.string ByteString
"EMERGENCY" forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Emergency)
pPath :: AB.Parser (Seq.Seq Path)
{-# INLINABLE pPath #-}
pPath :: Parser ByteString (Seq Path)
pPath = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pPath") forall a b. (a -> b) -> a -> b
$ do
forall a. (a -> a) -> a
fix (\Seq Path -> Parser ByteString (Seq Path)
k Seq Path
ps -> ((Parser ByteString Path
pPush forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString Path
pAttr) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Path
p -> Seq Path -> Parser ByteString (Seq Path)
k (Seq Path
ps forall a. Seq a -> a -> Seq a
Seq.|> Path
p)) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure Seq Path
ps)
forall a. Monoid a => a
mempty
where
{-# INLINE pPush #-}
pPush :: AB.Parser Path
pPush :: Parser ByteString Path
pPush = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pPush") forall a b. (a -> b) -> a -> b
$ do
Segment
seg <- Parser ByteString Segment
pSegment forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Word8 -> Bool) -> Parser ()
AB.skipWhile (forall a. Eq a => a -> a -> Bool
== Word8
32)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Segment -> Path
Push Segment
seg)
{-# INLINE pAttr #-}
pAttr :: AB.Parser Path
pAttr :: Parser ByteString Path
pAttr = do
Key
k <- Parser ByteString Key
pKey forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
61)
Value
v <- Parser ByteString Value
pValue forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Word8 -> Bool) -> Parser ()
AB.skipWhile (forall a. Eq a => a -> a -> Bool
== Word8
32)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Key -> Value -> Path
Attr Key
k Value
v)
pSegment :: AB.Parser Segment
pSegment :: Parser ByteString Segment
pSegment = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pSegment") forall a b. (a -> b) -> a -> b
$ do
(Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
47) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"/"
Text
bl <- ByteString -> Parser ByteString Text
pUtf8LtoL forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString -> Parser ByteString ByteString
pDecodePercents forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Word8 -> Bool) -> Parser ByteString
AB.takeWhile (forall a. Eq a => a -> a -> Bool
/= Word8
32)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. ToSegment a => a -> Segment
segment Text
bl)
pKey :: AB.Parser Key
pKey :: Parser ByteString Key
pKey = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pKey") forall a b. (a -> b) -> a -> b
$ do
Text
bl <- ByteString -> Parser ByteString Text
pUtf8LtoL forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString -> Parser ByteString ByteString
pDecodePercents
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Word8 -> Bool) -> Parser ByteString
AB.takeWhile (\Word8
w -> Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
61 Bool -> Bool -> Bool
&& Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
32)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. ToKey a => a -> Key
key Text
bl)
pValue :: AB.Parser Value
pValue :: Parser ByteString Value
pValue = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pValue") forall a b. (a -> b) -> a -> b
$ do
Text
bl <- ByteString -> Parser ByteString Text
pUtf8LtoL forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString -> Parser ByteString ByteString
pDecodePercents forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Word8 -> Bool) -> Parser ByteString
AB.takeWhile (forall a. Eq a => a -> a -> Bool
/= Word8
32)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. ToValue a => a -> Value
value Text
bl)
pMessage :: AB.Parser Message
{-# INLINE pMessage #-}
pMessage :: Parser ByteString Message
pMessage = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pMessage") forall a b. (a -> b) -> a -> b
$ do
ByteString
b <- (Word8 -> Bool) -> Parser ByteString
AB.takeWhile (\Word8
w -> Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
10 Bool -> Bool -> Bool
&& Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
13)
Text
tl <- ByteString -> Parser ByteString Text
pUtf8LtoL forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString -> Parser ByteString ByteString
pDecodePercents ByteString
b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. ToMessage a => a -> Message
message Text
tl)
pUtf8LtoL :: BL.ByteString -> AB.Parser TL.Text
{-# INLINE pUtf8LtoL #-}
pUtf8LtoL :: ByteString -> Parser ByteString Text
pUtf8LtoL = \ByteString
bl -> case ByteString -> Either UnicodeException Text
TL.decodeUtf8' ByteString
bl of
Right Text
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
x
Left UnicodeException
e -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (forall a. Show a => a -> String
show UnicodeException
e) forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pUtf8LtoL"
pNumPercent :: AB.Parser Word8
{-# INLINE pNumPercent #-}
pNumPercent :: Parser ByteString Word8
pNumPercent = (forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum2Nibbles") forall a b. (a -> b) -> a -> b
$ do
(Word8 -> Bool) -> Parser ()
AB.skip (forall a. Eq a => a -> a -> Bool
== Word8
37)
Word8
wh <- Parser ByteString Word8
pHexDigit
Word8
wl <- Parser ByteString Word8
pHexDigit
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Bits a => a -> MonthOfYear -> a
shiftL Word8
wh MonthOfYear
4 forall a. Num a => a -> a -> a
+ Word8
wl)
pHexDigit :: AB.Parser Word8
{-# INLINE pHexDigit #-}
pHexDigit :: Parser ByteString Word8
pHexDigit = forall a. (Word8 -> a) -> (a -> Bool) -> Parser a
AB.satisfyWith
(\case Word8
w | Word8
w forall a. Ord a => a -> a -> Bool
>= Word8
48 Bool -> Bool -> Bool
&& Word8
w forall a. Ord a => a -> a -> Bool
<= Word8
57 -> Word8
w forall a. Num a => a -> a -> a
- Word8
48
| Word8
w forall a. Ord a => a -> a -> Bool
>= Word8
65 Bool -> Bool -> Bool
&& Word8
w forall a. Ord a => a -> a -> Bool
<= Word8
70 -> Word8
w forall a. Num a => a -> a -> a
- Word8
55
| Word8
w forall a. Ord a => a -> a -> Bool
>= Word8
97 Bool -> Bool -> Bool
&& Word8
w forall a. Ord a => a -> a -> Bool
<= Word8
102 -> Word8
w forall a. Num a => a -> a -> a
- Word8
87
| Bool
otherwise -> Word8
99)
(\Word8
w -> Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
99)
pDecodePercents :: B.ByteString -> AB.Parser BL.ByteString
{-# INLINE pDecodePercents #-}
pDecodePercents :: ByteString -> Parser ByteString ByteString
pDecodePercents = ByteString -> Parser ByteString ByteString
pDecodePercentsL forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BL.fromStrict
pDecodePercentsL :: BL.ByteString -> AB.Parser BL.ByteString
{-# INLINABLE pDecodePercentsL #-}
pDecodePercentsL :: ByteString -> Parser ByteString ByteString
pDecodePercentsL = \ByteString
bl ->
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall r. Result r -> Either String r
ABL.eitherResult (forall a. Parser a -> ByteString -> Result a
ABL.parse Parser ByteString ByteString
p ByteString
bl))
where
p :: AB.Parser BL.ByteString
p :: Parser ByteString ByteString
p = forall t. Chunk t => Parser t Bool
AB.atEnd forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
Bool
False -> forall a. (a -> a) -> a
fix forall a b. (a -> b) -> a -> b
$ \Parser ByteString ByteString
k -> do
ByteString
b <- Parser (Maybe Word8)
AB.peekWord8 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe Word8
Nothing -> forall (f :: * -> *) a. Alternative f => f a
empty
Just Word8
37 -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word8 -> ByteString
B.singleton Parser ByteString Word8
pNumPercent
Just Word8
_ -> (Word8 -> Bool) -> Parser ByteString
AB.takeWhile1 (\Word8
w -> Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
37)
[ByteString]
bls <- forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser ByteString ByteString
k forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
AB.endOfInput
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Monoid a => [a] -> a
mconcat (ByteString -> ByteString
BL.fromStrict ByteString
b forall a. a -> [a] -> [a]
: [ByteString]
bls))