{-# LANGUAGE CPP #-}
-- |
--
-- Builder structures for 'JChar's
--
module Waargonaut.Encode.Builder.JChar (jCharBuilder) where

import           Control.Lens                     (review)

#if !MIN_VERSION_base(4,11,0)
import           Data.Monoid                      ((<>))
#endif

import           Data.Digit                       (HeXaDeCiMaL, charHeXaDeCiMaL)

import           Waargonaut.Encode.Builder.Types  (Builder (..))
import           Waargonaut.Types.JChar           (JChar (..))
import           Waargonaut.Types.JChar.Escaped   (Escaped (..))
import           Waargonaut.Types.JChar.HexDigit4 (HexDigit4 (..))
import           Waargonaut.Types.JChar.Unescaped (_Unescaped)
import           Waargonaut.Types.Whitespace      (unescapedWhitespaceChar)

-- | Using the given function, return the builder for a single 'JChar'.
jCharBuilder
  :: ( Monoid b
     , HeXaDeCiMaL digit
     )
  => Builder t b
  -> JChar digit
  -> b
jCharBuilder :: Builder t b -> JChar digit -> b
jCharBuilder Builder t b
bldr (UnescapedJChar Unescaped
c) = Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr (AReview Char Unescaped -> Unescaped -> Char
forall b (m :: * -> *) t. MonadReader b m => AReview t b -> m t
review AReview Char Unescaped
forall a. AsUnescaped a => Prism' a Unescaped
_Unescaped Unescaped
c)
jCharBuilder Builder t b
bldr (EscapedJChar Escaped digit
jca) = Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr Char
'\\' b -> b -> b
forall a. Semigroup a => a -> a -> a
<> case Escaped digit
jca of
    Escaped digit
QuotationMark           -> Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr Char
'"'
    Escaped digit
ReverseSolidus          -> Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr Char
'\\'
    Escaped digit
Solidus                 -> Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr Char
'/'
    Escaped digit
Backspace               -> Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr Char
'b'
    (WhiteSpace Whitespace
ws)         -> Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr (Whitespace -> Char
unescapedWhitespaceChar Whitespace
ws)
    Hex (HexDigit4 digit
a digit
b digit
c digit
d) -> Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr Char
'u' b -> b -> b
forall a. Semigroup a => a -> a -> a
<> (digit -> b) -> [digit] -> b
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap digit -> b
hexChar [digit
a,digit
b,digit
c,digit
d]
  where
    hexChar :: digit -> b
hexChar =
      Builder t b -> Char -> b
forall t b. Builder t b -> Char -> b
fromChar Builder t b
bldr (Char -> b) -> (digit -> Char) -> digit -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AReview Char digit -> digit -> Char
forall b (m :: * -> *) t. MonadReader b m => AReview t b -> m t
review AReview Char digit
forall d. HeXaDeCiMaL d => Prism' Char d
charHeXaDeCiMaL