{-# 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 () -- To make sure module instances are available here too.

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)

--------------------------------------------------------------------------------

-- | If sucessful, parsing will stop after the first CR or LF newline marker if
-- any, otherwise it will consume all input.
log :: AB.Parser Log
log :: Parser Log
log = (Parser Log -> String -> Parser Log
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"log") (Parser Log -> Parser Log) -> Parser Log -> Parser Log
forall a b. (a -> b) -> a -> b
$ do
  UTCTime
t <- (Word8 -> Bool) -> Parser ()
AB.skipWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
32) Parser () -> Parser ByteString UTCTime -> Parser ByteString UTCTime
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString UTCTime
pIso8601 -- :space:
  Seq Path
p <- (Word8 -> Bool) -> Parser ()
AB.skipWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
32) Parser ()
-> Parser ByteString (Seq Path) -> Parser ByteString (Seq Path)
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString (Seq Path)
pPath
  Level
l <- (Word8 -> Bool) -> Parser ()
AB.skipWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
32) Parser () -> Parser ByteString Level -> Parser ByteString Level
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString Level
pLevel
  Message
m <- (Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
32) Parser () -> Parser ByteString Message -> Parser ByteString Message
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString Message
pMessage
  Log -> Parser Log
forall a. a -> Parser ByteString a
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
pIso8601 :: Parser ByteString UTCTime
pIso8601 = (Parser ByteString UTCTime -> String -> Parser ByteString UTCTime
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pIso8601") (Parser ByteString UTCTime -> Parser ByteString UTCTime)
-> Parser ByteString UTCTime -> Parser ByteString UTCTime
forall a b. (a -> b) -> a -> b
$ do
  Word16
year <- (Parser Word16
pNum4Digits Parser Word16 -> String -> Parser Word16
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"year") Parser Word16 -> Parser () -> Parser Word16
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
45) Parser () -> String -> Parser ()
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"-")
  Word8
month <- (Parser Word8
pNum2Digits Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"month") Parser Word8 -> Parser () -> Parser Word8
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
45) Parser () -> String -> Parser ()
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"-")
  Word8
day <- (Parser Word8
pNum2Digits Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"day") Parser Word8 -> Parser () -> Parser Word8
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
84) Parser () -> String -> Parser ()
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"T")
  Just Day
tday <- Maybe Day -> Parser ByteString (Maybe Day)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Year -> MonthOfYear -> MonthOfYear -> Maybe Day
Time.fromGregorianValid
     (Word16 -> Year
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
year) (Word8 -> MonthOfYear
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
month) (Word8 -> MonthOfYear
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
day))
  Word8
hour <- (Parser Word8
pNum2Digits Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"hour") Parser Word8 -> Parser () -> Parser Word8
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
58) Parser () -> String -> Parser ()
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
":")
  Word8
min' <- (Parser Word8
pNum2Digits Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"minute") Parser Word8 -> Parser () -> Parser Word8
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
58) Parser () -> String -> Parser ()
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
":")
  Word8
sec <- (Parser Word8
pNum2Digits Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"second") Parser Word8 -> Parser () -> Parser Word8
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
46) Parser () -> String -> Parser ()
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
".")
  Word32
nsec <- (Parser Word32
pNum9Digits Parser Word32 -> String -> Parser Word32
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"nanosecond") Parser Word32 -> Parser () -> Parser Word32
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ((Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
90) Parser () -> String -> Parser ()
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"Z")
  Just TimeOfDay
ttod <- Maybe TimeOfDay -> Parser ByteString (Maybe TimeOfDay)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (MonthOfYear -> MonthOfYear -> Pico -> Maybe TimeOfDay
Time.makeTimeOfDayValid
     (Word8 -> MonthOfYear
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
hour) (Word8 -> MonthOfYear
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
min')
     (Word8 -> Pico
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
sec Pico -> Pico -> Pico
forall a. Num a => a -> a -> a
+ (Word32 -> Pico
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
nsec Pico -> Pico -> Pico
forall a. Fractional a => a -> a -> a
/ Pico
1000000000)))
  UTCTime -> Parser ByteString UTCTime
forall a. a -> Parser ByteString a
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
pNum1Digit :: Parser Word8
pNum1Digit = (Word8 -> Word8) -> (Word8 -> Bool) -> Parser Word8
forall a. (Word8 -> a) -> (a -> Bool) -> Parser a
AB.satisfyWith (Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
subtract Word8
48) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
10) Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum1Digit"

pNum2Digits :: AB.Parser Word8
pNum2Digits :: Parser Word8
pNum2Digits = (Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum2Digits") (Parser Word8 -> Parser Word8) -> Parser Word8 -> Parser Word8
forall a b. (a -> b) -> a -> b
$ do
  Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
(+) (Word8 -> Word8 -> Word8)
-> Parser Word8 -> Parser ByteString (Word8 -> Word8)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word8 -> Word8) -> Parser Word8 -> Parser Word8
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
* Word8
10) Parser Word8
pNum1Digit Parser ByteString (Word8 -> Word8) -> Parser Word8 -> Parser Word8
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
pNum1Digit

pNum4Digits :: AB.Parser Word16
pNum4Digits :: Parser Word16
pNum4Digits = (Parser Word16 -> String -> Parser Word16
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum4Digits") (Parser Word16 -> Parser Word16) -> Parser Word16 -> Parser Word16
forall a b. (a -> b) -> a -> b
$ do
  (\Word16
a Word16
b Word16
c Word16
d -> Word16
a Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ Word16
b Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ Word16
c Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ Word16
d)
     (Word16 -> Word16 -> Word16 -> Word16 -> Word16)
-> Parser Word16
-> Parser ByteString (Word16 -> Word16 -> Word16 -> Word16)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word8 -> Word16) -> Parser Word8 -> Parser Word16
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
* Word16
1000) (Word16 -> Word16) -> (Word8 -> Word16) -> Word8 -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser ByteString (Word16 -> Word16 -> Word16 -> Word16)
-> Parser Word16 -> Parser ByteString (Word16 -> Word16 -> Word16)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word16) -> Parser Word8 -> Parser Word16
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
* Word16
100) (Word16 -> Word16) -> (Word8 -> Word16) -> Word8 -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser ByteString (Word16 -> Word16 -> Word16)
-> Parser Word16 -> Parser ByteString (Word16 -> Word16)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word16) -> Parser Word8 -> Parser Word16
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
* Word16
10) (Word16 -> Word16) -> (Word8 -> Word16) -> Word8 -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
          Parser ByteString (Word16 -> Word16)
-> Parser Word16 -> Parser Word16
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word16) -> Parser Word8 -> Parser Word16
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Parser Word8
pNum1Digit

pNum9Digits :: AB.Parser Word32
pNum9Digits :: Parser Word32
pNum9Digits = (Parser Word32 -> String -> Parser Word32
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum9Digits") (Parser Word32 -> Parser Word32) -> Parser Word32 -> Parser Word32
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 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
b Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
c Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
d Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
e Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
f Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
g Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
h Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
i)
     (Word32
 -> Word32
 -> Word32
 -> Word32
 -> Word32
 -> Word32
 -> Word32
 -> Word32
 -> Word32
 -> Word32)
-> Parser Word32
-> Parser
     ByteString
     (Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
100000000) (Word32 -> Word32) -> (Word8 -> Word32) -> Word8 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser
  ByteString
  (Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32)
-> Parser Word32
-> Parser
     ByteString
     (Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32
      -> Word32)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
10000000) (Word32 -> Word32) -> (Word8 -> Word32) -> Word8 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser
  ByteString
  (Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32
   -> Word32)
-> Parser Word32
-> Parser
     ByteString
     (Word32
      -> Word32 -> Word32 -> Word32 -> Word32 -> Word32 -> Word32)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
1000000) (Word32 -> Word32) -> (Word8 -> Word32) -> Word8 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser
  ByteString
  (Word32
   -> Word32 -> Word32 -> Word32 -> Word32 -> Word32 -> Word32)
-> Parser Word32
-> Parser
     ByteString
     (Word32 -> Word32 -> Word32 -> Word32 -> Word32 -> Word32)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
100000) (Word32 -> Word32) -> (Word8 -> Word32) -> Word8 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser
  ByteString
  (Word32 -> Word32 -> Word32 -> Word32 -> Word32 -> Word32)
-> Parser Word32
-> Parser
     ByteString (Word32 -> Word32 -> Word32 -> Word32 -> Word32)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
10000) (Word32 -> Word32) -> (Word8 -> Word32) -> Word8 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser ByteString (Word32 -> Word32 -> Word32 -> Word32 -> Word32)
-> Parser Word32
-> Parser ByteString (Word32 -> Word32 -> Word32 -> Word32)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
1000) (Word32 -> Word32) -> (Word8 -> Word32) -> Word8 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser ByteString (Word32 -> Word32 -> Word32 -> Word32)
-> Parser Word32 -> Parser ByteString (Word32 -> Word32 -> Word32)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
100) (Word32 -> Word32) -> (Word8 -> Word32) -> Word8 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser ByteString (Word32 -> Word32 -> Word32)
-> Parser Word32 -> Parser ByteString (Word32 -> Word32)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
10) (Word32 -> Word32) -> (Word8 -> Word32) -> Word8 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8
pNum1Digit
     Parser ByteString (Word32 -> Word32)
-> Parser Word32 -> Parser Word32
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32) -> Parser Word8 -> Parser Word32
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Parser Word8
pNum1Digit

pLevel :: AB.Parser Level
pLevel :: Parser ByteString Level
pLevel = (Parser ByteString Level -> String -> Parser ByteString Level
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pLevel")
  -- In decreasing frequency we expect logs to happen.
  -- We expect 'Debug' to mostly be muted, so 'Info' is prefered.
  (ByteString -> Parser ByteString
AB.string ByteString
"INFO"      Parser ByteString -> Level -> Parser ByteString Level
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Info)     Parser ByteString Level
-> Parser ByteString Level -> Parser ByteString Level
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (ByteString -> Parser ByteString
AB.string ByteString
"DEBUG"     Parser ByteString -> Level -> Parser ByteString Level
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Debug)    Parser ByteString Level
-> Parser ByteString Level -> Parser ByteString Level
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (ByteString -> Parser ByteString
AB.string ByteString
"NOTICE"    Parser ByteString -> Level -> Parser ByteString Level
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Notice)   Parser ByteString Level
-> Parser ByteString Level -> Parser ByteString Level
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (ByteString -> Parser ByteString
AB.string ByteString
"WARNING"   Parser ByteString -> Level -> Parser ByteString Level
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Warning)  Parser ByteString Level
-> Parser ByteString Level -> Parser ByteString Level
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (ByteString -> Parser ByteString
AB.string ByteString
"ERROR"     Parser ByteString -> Level -> Parser ByteString Level
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Error)    Parser ByteString Level
-> Parser ByteString Level -> Parser ByteString Level
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (ByteString -> Parser ByteString
AB.string ByteString
"CRITICAL"  Parser ByteString -> Level -> Parser ByteString Level
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Critical) Parser ByteString Level
-> Parser ByteString Level -> Parser ByteString Level
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (ByteString -> Parser ByteString
AB.string ByteString
"ALERT"     Parser ByteString -> Level -> Parser ByteString Level
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Alert)    Parser ByteString Level
-> Parser ByteString Level -> Parser ByteString Level
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (ByteString -> Parser ByteString
AB.string ByteString
"EMERGENCY" Parser ByteString -> Level -> Parser ByteString Level
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Level
Emergency)

pPath :: AB.Parser (Seq.Seq Path)
pPath :: Parser ByteString (Seq Path)
pPath = (Parser ByteString (Seq Path)
-> String -> Parser ByteString (Seq Path)
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pPath") (Parser ByteString (Seq Path) -> Parser ByteString (Seq Path))
-> Parser ByteString (Seq Path) -> Parser ByteString (Seq Path)
forall a b. (a -> b) -> a -> b
$ do
    ((Seq Path -> Parser ByteString (Seq Path))
 -> Seq Path -> Parser ByteString (Seq Path))
-> Seq Path -> Parser ByteString (Seq Path)
forall a. (a -> a) -> a
fix (\Seq Path -> Parser ByteString (Seq Path)
k Seq Path
ps -> ((Parser Path
pPush Parser Path -> Parser Path -> Parser Path
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Path
pAttr) Parser Path
-> (Path -> Parser ByteString (Seq Path))
-> Parser ByteString (Seq Path)
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
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 Seq Path -> Path -> Seq Path
forall a. Seq a -> a -> Seq a
Seq.|> Path
p)) Parser ByteString (Seq Path)
-> Parser ByteString (Seq Path) -> Parser ByteString (Seq Path)
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Seq Path -> Parser ByteString (Seq Path)
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Seq Path
ps)
        Seq Path
forall a. Monoid a => a
mempty
  where
    pPush :: AB.Parser Path
    pPush :: Parser Path
pPush = (Parser Path -> String -> Parser Path
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pPush") (Parser Path -> Parser Path) -> Parser Path -> Parser Path
forall a b. (a -> b) -> a -> b
$ do
      Segment
seg <- Parser Segment
pSegment Parser Segment -> Parser () -> Parser Segment
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Word8 -> Bool) -> Parser ()
AB.skipWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
32)
      Path -> Parser Path
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Segment -> Path
Push Segment
seg)
    pAttr :: AB.Parser Path
    pAttr :: Parser Path
pAttr = do
      Key
k <- Parser Key
pKey Parser Key -> Parser () -> Parser Key
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
61)
      Value
v <- Parser Value
pValue Parser Value -> Parser () -> Parser Value
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Word8 -> Bool) -> Parser ()
AB.skipWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
32)
      Path -> Parser Path
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Key -> Value -> Path
Attr Key
k Value
v)

pSegment :: AB.Parser Segment
pSegment :: Parser Segment
pSegment = (Parser Segment -> String -> Parser Segment
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pSegment") (Parser Segment -> Parser Segment)
-> Parser Segment -> Parser Segment
forall a b. (a -> b) -> a -> b
$ do
  (Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
47) Parser () -> String -> Parser ()
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"/"
  Text
bl <- ByteString -> Parser Text
pUtf8LtoL (ByteString -> Parser Text)
-> Parser ByteString ByteString -> Parser Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString -> Parser ByteString ByteString
pDecodePercents (ByteString -> Parser ByteString ByteString)
-> Parser ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Word8 -> Bool) -> Parser ByteString
AB.takeWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
32) -- :space:
  Segment -> Parser Segment
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Segment
forall a. ToSegment a => a -> Segment
segment Text
bl)

pKey :: AB.Parser Key
pKey :: Parser Key
pKey = (Parser Key -> String -> Parser Key
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pKey") (Parser Key -> Parser Key) -> Parser Key -> Parser Key
forall a b. (a -> b) -> a -> b
$ do
  Text
bl <- ByteString -> Parser Text
pUtf8LtoL (ByteString -> Parser Text)
-> Parser ByteString ByteString -> Parser Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString -> Parser ByteString ByteString
pDecodePercents
          (ByteString -> Parser ByteString ByteString)
-> Parser ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Word8 -> Bool) -> Parser ByteString
AB.takeWhile (\Word8
w -> Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
61 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
32) -- '=' or :space:
  Key -> Parser Key
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Key
forall a. ToKey a => a -> Key
key Text
bl)

pValue :: AB.Parser Value
pValue :: Parser Value
pValue = (Parser Value -> String -> Parser Value
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pValue") (Parser Value -> Parser Value) -> Parser Value -> Parser Value
forall a b. (a -> b) -> a -> b
$ do
  Text
bl <- ByteString -> Parser Text
pUtf8LtoL (ByteString -> Parser Text)
-> Parser ByteString ByteString -> Parser Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString -> Parser ByteString ByteString
pDecodePercents (ByteString -> Parser ByteString ByteString)
-> Parser ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Word8 -> Bool) -> Parser ByteString
AB.takeWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
32) -- :space:
  Value -> Parser Value
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Value
forall a. ToValue a => a -> Value
value Text
bl)

pMessage :: AB.Parser Message
pMessage :: Parser ByteString Message
pMessage = (Parser ByteString Message -> String -> Parser ByteString Message
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pMessage") (Parser ByteString Message -> Parser ByteString Message)
-> Parser ByteString Message -> Parser ByteString Message
forall a b. (a -> b) -> a -> b
$ do
  ByteString
b <- (Word8 -> Bool) -> Parser ByteString
AB.takeWhile (\Word8
w -> Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
10 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
13) -- CR and LF
  Text
tl <- ByteString -> Parser Text
pUtf8LtoL (ByteString -> Parser Text)
-> Parser ByteString ByteString -> Parser Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString -> Parser ByteString ByteString
pDecodePercents ByteString
b
  Message -> Parser ByteString Message
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Message
forall a. ToMessage a => a -> Message
message Text
tl)

pUtf8LtoL :: BL.ByteString -> AB.Parser TL.Text
pUtf8LtoL :: ByteString -> Parser Text
pUtf8LtoL = \ByteString
bl -> case ByteString -> Either UnicodeException Text
TL.decodeUtf8' ByteString
bl of
   Right Text
x -> Text -> Parser Text
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
x
   Left UnicodeException
e -> String -> Parser Text
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (UnicodeException -> String
forall a. Show a => a -> String
show UnicodeException
e) Parser Text -> String -> Parser Text
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pUtf8LtoL"

-- | Parse @\"%FF\"@. Always consumes 3 bytes from the input, if successful.
pNumPercent :: AB.Parser Word8
pNumPercent :: Parser Word8
pNumPercent = (Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
AB.<?> String
"pNum2Nibbles") (Parser Word8 -> Parser Word8) -> Parser Word8 -> Parser Word8
forall a b. (a -> b) -> a -> b
$ do
   (Word8 -> Bool) -> Parser ()
AB.skip (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
37) -- percent
   Word8
wh <- Parser Word8
pHexDigit
   Word8
wl <- Parser Word8
pHexDigit
   Word8 -> Parser Word8
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word8 -> MonthOfYear -> Word8
forall a. Bits a => a -> MonthOfYear -> a
shiftL Word8
wh MonthOfYear
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
wl)

pHexDigit :: AB.Parser Word8
pHexDigit :: Parser Word8
pHexDigit = (Word8 -> Word8) -> (Word8 -> Bool) -> Parser Word8
forall a. (Word8 -> a) -> (a -> Bool) -> Parser a
AB.satisfyWith
  (\case Word8
w | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
48 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<=  Word8
57 -> Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
48
           | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
65 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<=  Word8
70 -> Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
55
           | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
97 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
102 -> Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
87
           | Bool
otherwise -> Word8
99)
  (\Word8
w -> Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
99)

-- | Like 'pDecodePercentsL' but takes strict bytes.
pDecodePercents :: B.ByteString -> AB.Parser BL.ByteString
pDecodePercents :: ByteString -> Parser ByteString ByteString
pDecodePercents = ByteString -> Parser ByteString ByteString
pDecodePercentsL (ByteString -> Parser ByteString ByteString)
-> (ByteString -> ByteString)
-> ByteString
-> Parser ByteString ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BL.fromStrict

-- | Decodes all 'pNumPercent' occurences from the given input.
--
-- TODO: Make faster and more space efficient.
pDecodePercentsL :: BL.ByteString -> AB.Parser BL.ByteString
pDecodePercentsL :: ByteString -> Parser ByteString ByteString
pDecodePercentsL = \ByteString
bl ->
    (String -> Parser ByteString ByteString)
-> (ByteString -> Parser ByteString ByteString)
-> Either String ByteString
-> Parser ByteString ByteString
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Parser ByteString ByteString
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail ByteString -> Parser ByteString ByteString
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Result ByteString -> Either String ByteString
forall r. Result r -> Either String r
ABL.eitherResult (Parser ByteString ByteString -> ByteString -> Result ByteString
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 = Parser ByteString Bool
forall t. Chunk t => Parser t Bool
AB.atEnd Parser ByteString Bool
-> (Bool -> Parser ByteString ByteString)
-> Parser ByteString ByteString
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
          Bool
True -> ByteString -> Parser ByteString ByteString
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
forall a. Monoid a => a
mempty
          Bool
False -> (Parser ByteString ByteString -> Parser ByteString ByteString)
-> Parser ByteString ByteString
forall a. (a -> a) -> a
fix ((Parser ByteString ByteString -> Parser ByteString ByteString)
 -> Parser ByteString ByteString)
-> (Parser ByteString ByteString -> Parser ByteString ByteString)
-> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$ \Parser ByteString ByteString
k -> do
             ByteString
b <- Parser (Maybe Word8)
AB.peekWord8 Parser (Maybe Word8)
-> (Maybe Word8 -> Parser ByteString) -> Parser ByteString
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                Maybe Word8
Nothing -> Parser ByteString
forall a. Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a
empty
                Just Word8
37 -> (Word8 -> ByteString) -> Parser Word8 -> Parser ByteString
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word8 -> ByteString
B.singleton Parser Word8
pNumPercent
                Just Word8
_  -> (Word8 -> Bool) -> Parser ByteString
AB.takeWhile1 (\Word8
w -> Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
37)
             [ByteString]
bls <- Parser ByteString ByteString -> Parser ByteString [ByteString]
forall a. Parser ByteString a -> Parser ByteString [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser ByteString ByteString
k Parser ByteString [ByteString]
-> Parser () -> Parser ByteString [ByteString]
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall t. Chunk t => Parser t ()
AB.endOfInput
             ByteString -> Parser ByteString ByteString
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat (ByteString -> ByteString
BL.fromStrict ByteString
b ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
bls))