module PercentEncoding.TextBuilders where

import qualified Data.CharSet as CharSet
import qualified Data.Text as Text
import qualified PercentEncoding.Charsets as Charsets
import qualified PercentEncoding.Utf8CharView as Utf8CharView
import Platform.Prelude
import TextBuilder

-- | Apply URL-encoding to text
urlEncodedText :: Text -> TextBuilder
urlEncodedText :: Text -> TextBuilder
urlEncodedText =
  (Char -> TextBuilder) -> [Char] -> TextBuilder
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Char -> TextBuilder
urlEncodedChar ([Char] -> TextBuilder) -> (Text -> [Char]) -> Text -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Text -> [Char]
Text.unpack

urlEncodedChar :: Char -> TextBuilder
urlEncodedChar :: Char -> TextBuilder
urlEncodedChar Char
c =
  if Char -> CharSet -> Bool
CharSet.member Char
c CharSet
Charsets.passthrough
    then Char -> TextBuilder
char Char
c
    else
      Char -> Utf8CharView
Utf8CharView.char
        Char
c
        ( \Word8
b1 ->
            Word8 -> TextBuilder
urlEncodedByte Word8
b1
        )
        ( \Word8
b1 Word8
b2 ->
            Word8 -> TextBuilder
urlEncodedByte Word8
b1 TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> TextBuilder
urlEncodedByte Word8
b2
        )
        ( \Word8
b1 Word8
b2 Word8
b3 ->
            [TextBuilder] -> TextBuilder
forall a. Monoid a => [a] -> a
mconcat [Word8 -> TextBuilder
urlEncodedByte Word8
b1, Word8 -> TextBuilder
urlEncodedByte Word8
b2, Word8 -> TextBuilder
urlEncodedByte Word8
b3]
        )
        ( \Word8
b1 Word8
b2 Word8
b3 Word8
b4 ->
            [TextBuilder] -> TextBuilder
forall a. Monoid a => [a] -> a
mconcat [Word8 -> TextBuilder
urlEncodedByte Word8
b1, Word8 -> TextBuilder
urlEncodedByte Word8
b2, Word8 -> TextBuilder
urlEncodedByte Word8
b3, Word8 -> TextBuilder
urlEncodedByte Word8
b4]
        )

urlEncodedByte :: Word8 -> TextBuilder
urlEncodedByte :: Word8 -> TextBuilder
urlEncodedByte Word8
x = Char -> TextBuilder
char Char
'%' TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> TextBuilder
forall a. (FiniteBits a, Integral a) => a -> TextBuilder
hexadecimal Word8
x