    {-# LANGUAGE CPP #-}

    {-# OPTIONS_GHC -fsimpl-tick-factor=40000 #-}

    ------------------------------------------------------------------------------
    -- |
    -- Module:      Blaze.ByteString.Builder.Html.Word
    -- Copyright:   (c) 2016 Dylan Simon
    -- License:     BSD3
    -- Maintainer:  https://github.com/blaze-builder
    -- Stability:   stable
    --
    -- 'W.Write's and 'B.Builder's for serializing HTML escaped 'Word8' characters
    -- and 'BS.ByteString's that have already been appropriately encoded into HTML by
    -- escaping basic ASCII character references but leaving other bytes untouched.
    --
    ------------------------------------------------------------------------------

    module Blaze.ByteString.Builder.Html.Word
      ( wordHtmlEscaped
        -- * Writing HTML escaped bytes to a buffer
      , writeHtmlEscapedWord
        -- * Creating Builders from HTML escaped bytes
      , fromHtmlEscapedWord
      , fromHtmlEscapedWordList
      , fromHtmlEscapedByteString
      , fromHtmlEscapedLazyByteString
      ) where

    import qualified Blaze.ByteString.Builder.Compat.Write as W
    import qualified Data.ByteString as BS
    import qualified Data.ByteString.Builder as B
    import qualified Data.ByteString.Builder.Prim as P
    import           Data.ByteString.Internal (c2w)
    import qualified Data.ByteString.Lazy as BSL
    import           Data.Word (Word8)

    {-# INLINE wordHtmlEscaped #-}
    wordHtmlEscaped :: P.BoundedPrim Word8
    wordHtmlEscaped :: BoundedPrim Word8
    wordHtmlEscaped =
      (Word8 -> Bool)
    -> BoundedPrim Word8 -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a.
    (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
    P.condB (Word8 -> Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    >  Char -> Word8
    c2w Char
    '>' ) ((Word8 -> Bool)
    -> BoundedPrim Word8 -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a.
    (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
    P.condB (Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '\DEL') BoundedPrim Word8
    forall a. BoundedPrim a
    P.emptyB (BoundedPrim Word8 -> BoundedPrim Word8)
    -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a b. (a -> b) -> a -> b
    $ FixedPrim Word8 -> BoundedPrim Word8
    forall a. FixedPrim a -> BoundedPrim a
    P.liftFixedToBounded FixedPrim Word8
    P.word8) (BoundedPrim Word8 -> BoundedPrim Word8)
    -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a b. (a -> b) -> a -> b
    $
      (Word8 -> Bool)
    -> BoundedPrim Word8 -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a.
    (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
    P.condB (Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '<' ) ((Char, (Char, (Char, Char))) -> BoundedPrim Word8
    forall {a}. (Char, (Char, (Char, Char))) -> BoundedPrim a
    fixed4 (Char
    '&',(Char
    'l',(Char
    't',Char
    ';')))) (BoundedPrim Word8 -> BoundedPrim Word8)
    -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a b. (a -> b) -> a -> b
    $        -- &lt;
      (Word8 -> Bool)
    -> BoundedPrim Word8 -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a.
    (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
    P.condB (Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '>' ) ((Char, (Char, (Char, Char))) -> BoundedPrim Word8
    forall {a}. (Char, (Char, (Char, Char))) -> BoundedPrim a
    fixed4 (Char
    '&',(Char
    'g',(Char
    't',Char
    ';')))) (BoundedPrim Word8 -> BoundedPrim Word8)
    -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a b. (a -> b) -> a -> b
    $        -- &gt;
      (Word8 -> Bool)
    -> BoundedPrim Word8 -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a.
    (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
    P.condB (Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '&' ) ((Char, (Char, (Char, (Char, Char)))) -> BoundedPrim Word8
    forall {a}. (Char, (Char, (Char, (Char, Char)))) -> BoundedPrim a
    fixed5 (Char
    '&',(Char
    'a',(Char
    'm',(Char
    'p',Char
    ';'))))) (BoundedPrim Word8 -> BoundedPrim Word8)
    -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a b. (a -> b) -> a -> b
    $  -- &amp;
      (Word8 -> Bool)
    -> BoundedPrim Word8 -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a.
    (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
    P.condB (Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '"' ) ((Char, (Char, (Char, (Char, (Char, Char))))) -> BoundedPrim Word8
    forall {a}.
    (Char, (Char, (Char, (Char, (Char, Char))))) -> BoundedPrim a
    fixed6 (Char
    '&',(Char
    'q',(Char
    'u',(Char
    'o',(Char
    't',Char
    ';')))))) (BoundedPrim Word8 -> BoundedPrim Word8)
    -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a b. (a -> b) -> a -> b
    $  -- &quot;
      (Word8 -> Bool)
    -> BoundedPrim Word8 -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a.
    (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
    P.condB (Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '\'') ((Char, (Char, (Char, (Char, Char)))) -> BoundedPrim Word8
    forall {a}. (Char, (Char, (Char, (Char, Char)))) -> BoundedPrim a
    fixed5 (Char
    '&',(Char
    '#',(Char
    '3',(Char
    '9',Char
    ';'))))) (BoundedPrim Word8 -> BoundedPrim Word8)
    -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a b. (a -> b) -> a -> b
    $  -- &#39;
      (Word8 -> Bool)
    -> BoundedPrim Word8 -> BoundedPrim Word8 -> BoundedPrim Word8
    forall a.
    (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
    P.condB (\Word8
    c -> Word8
    c Word8 -> Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Char -> Word8
    c2w Char
    ' ' Bool -> Bool -> Bool
    || Word8
    c Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '\t' Bool -> Bool -> Bool
    || Word8
    c Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '\n' Bool -> Bool -> Bool
    || Word8
    c Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char -> Word8
    c2w Char
    '\r')
            (FixedPrim Word8 -> BoundedPrim Word8
    forall a. FixedPrim a -> BoundedPrim a
    P.liftFixedToBounded FixedPrim Word8
    P.word8) BoundedPrim Word8
    forall a. BoundedPrim a
    P.emptyB
      where
      {-# INLINE fixed4 #-}
      fixed4 :: (Char, (Char, (Char, Char))) -> BoundedPrim a
    fixed4 (Char, (Char, (Char, Char)))
    x = FixedPrim a -> BoundedPrim a
    forall a. FixedPrim a -> BoundedPrim a
    P.liftFixedToBounded (FixedPrim a -> BoundedPrim a) -> FixedPrim a -> BoundedPrim a
    forall a b. (a -> b) -> a -> b
    $ (Char, (Char, (Char, Char))) -> a -> (Char, (Char, (Char, Char)))
    forall a b. a -> b -> a
    const (Char, (Char, (Char, Char)))
    x (a -> (Char, (Char, (Char, Char))))
    -> FixedPrim (Char, (Char, (Char, Char))) -> FixedPrim a
    forall (f :: * -> *) b a. Contravariant f => (b -> a) -> f a -> f b
    P.>$<
        FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, (Char, Char))
    -> FixedPrim (Char, (Char, (Char, Char)))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, Char) -> FixedPrim (Char, (Char, Char))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char -> FixedPrim Char -> FixedPrim (Char, Char)
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8
      {-# INLINE fixed5 #-}
      fixed5 :: (Char, (Char, (Char, (Char, Char)))) -> BoundedPrim a
    fixed5 (Char, (Char, (Char, (Char, Char))))
    x = FixedPrim a -> BoundedPrim a
    forall a. FixedPrim a -> BoundedPrim a
    P.liftFixedToBounded (FixedPrim a -> BoundedPrim a) -> FixedPrim a -> BoundedPrim a
    forall a b. (a -> b) -> a -> b
    $ (Char, (Char, (Char, (Char, Char))))
    -> a -> (Char, (Char, (Char, (Char, Char))))
    forall a b. a -> b -> a
    const (Char, (Char, (Char, (Char, Char))))
    x (a -> (Char, (Char, (Char, (Char, Char)))))
    -> FixedPrim (Char, (Char, (Char, (Char, Char)))) -> FixedPrim a
    forall (f :: * -> *) b a. Contravariant f => (b -> a) -> f a -> f b
    P.>$<
        FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, (Char, (Char, Char)))
    -> FixedPrim (Char, (Char, (Char, (Char, Char))))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, (Char, Char))
    -> FixedPrim (Char, (Char, (Char, Char)))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, Char) -> FixedPrim (Char, (Char, Char))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char -> FixedPrim Char -> FixedPrim (Char, Char)
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8
      {-# INLINE fixed6 #-}
      fixed6 :: (Char, (Char, (Char, (Char, (Char, Char))))) -> BoundedPrim a
    fixed6 (Char, (Char, (Char, (Char, (Char, Char)))))
    x = FixedPrim a -> BoundedPrim a
    forall a. FixedPrim a -> BoundedPrim a
    P.liftFixedToBounded (FixedPrim a -> BoundedPrim a) -> FixedPrim a -> BoundedPrim a
    forall a b. (a -> b) -> a -> b
    $ (Char, (Char, (Char, (Char, (Char, Char)))))
    -> a -> (Char, (Char, (Char, (Char, (Char, Char)))))
    forall a b. a -> b -> a
    const (Char, (Char, (Char, (Char, (Char, Char)))))
    x (a -> (Char, (Char, (Char, (Char, (Char, Char))))))
    -> FixedPrim (Char, (Char, (Char, (Char, (Char, Char)))))
    -> FixedPrim a
    forall (f :: * -> *) b a. Contravariant f => (b -> a) -> f a -> f b
    P.>$<
        FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, (Char, (Char, (Char, Char))))
    -> FixedPrim (Char, (Char, (Char, (Char, (Char, Char)))))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, (Char, (Char, Char)))
    -> FixedPrim (Char, (Char, (Char, (Char, Char))))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, (Char, Char))
    -> FixedPrim (Char, (Char, (Char, Char)))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char
    -> FixedPrim (Char, Char) -> FixedPrim (Char, (Char, Char))
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8 FixedPrim Char -> FixedPrim Char -> FixedPrim (Char, Char)
    forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
    P.>*< FixedPrim Char
    P.char8

    -- | Write a HTML escaped byte to a bufffer.
    writeHtmlEscapedWord :: Word8 -> W.Write
    writeHtmlEscapedWord :: Word8 -> Write
    writeHtmlEscapedWord = BoundedPrim Word8 -> Word8 -> Write
    forall a. BoundedPrim a -> a -> Write
    W.writePrimBounded BoundedPrim Word8
    wordHtmlEscaped

    -- | /O(1)./ Serialize a HTML escaped byte.
    fromHtmlEscapedWord :: Word8 -> B.Builder
    fromHtmlEscapedWord :: Word8 -> Builder
    fromHtmlEscapedWord = BoundedPrim Word8 -> Word8 -> Builder
    forall a. BoundedPrim a -> a -> Builder
    P.primBounded BoundedPrim Word8
    wordHtmlEscaped

    -- | /O(n)/. Serialize a HTML escaped list of bytes.
    fromHtmlEscapedWordList :: [Word8] -> B.Builder
    fromHtmlEscapedWordList :: [Word8] -> Builder
    fromHtmlEscapedWordList = BoundedPrim Word8 -> [Word8] -> Builder
    forall a. BoundedPrim a -> [a] -> Builder
    P.primMapListBounded BoundedPrim Word8
    wordHtmlEscaped

    -- | /O(n)/. Serialize a HTML escaped 'BS.ByteString'.
    fromHtmlEscapedByteString :: BS.ByteString -> B.Builder
    fromHtmlEscapedByteString :: ByteString -> Builder
    fromHtmlEscapedByteString = BoundedPrim Word8 -> ByteString -> Builder
    P.primMapByteStringBounded BoundedPrim Word8
    wordHtmlEscaped

    -- | /O(n)/. Serialize a HTML escaped lazy 'BSL.ByteString'.
    fromHtmlEscapedLazyByteString :: BSL.ByteString -> B.Builder
    fromHtmlEscapedLazyByteString :: ByteString -> Builder
    fromHtmlEscapedLazyByteString = BoundedPrim Word8 -> ByteString -> Builder
    P.primMapLazyByteStringBounded BoundedPrim Word8
    wordHtmlEscaped