{-# LANGUAGE DeriveFoldable         #-}
{-# LANGUAGE DeriveFunctor          #-}
{-# LANGUAGE DeriveTraversable      #-}
{-# LANGUAGE FlexibleContexts       #-}
{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses  #-}
{-# LANGUAGE NoImplicitPrelude      #-}
{-# LANGUAGE RankNTypes             #-}
{-# LANGUAGE TypeFamilies           #-}
-- | Types and functions for handling characters in JSON.
module Waargonaut.Types.JChar
  (
    -- * Types
    JChar (..)
  , AsJChar (..)
  , HasJChar (..)

    -- * Parser
  , parseJChar

    -- * Conversion
  , utf8CharToJChar
  , jCharToUtf8Char
  , jCharToChar
  , charToJChar
  ) where

import           Prelude                          (Char, Eq, Ord, Show,
                                                   otherwise, (/=))

import           Control.Category                 (id, (.))
import           Control.Lens                     (Lens', Prism', preview,
                                                   prism, review)

import           Control.Applicative              ((<$>), (<|>))

import           Data.Bits                        ((.&.))
import           Data.Char                        (ord)
import           Data.Either                      (Either (..))
import           Data.Foldable                    (Foldable, asum)
import           Data.Function                    (($))
import           Data.Functor                     (Functor)
import           Data.Maybe                       (Maybe (..), fromMaybe)
import           Data.Traversable                 (Traversable)

import qualified Data.Text.Internal               as Text

import           Data.Digit                       (HeXDigit, HeXaDeCiMaL)
import qualified Data.Digit                       as D

import           Text.Parser.Char                 (CharParsing)

import           Waargonaut.Types.JChar.HexDigit4 (HexDigit4 (..))

import           Waargonaut.Types.JChar.Escaped   (AsEscaped (..), Escaped (..),
                                                   charToEscaped, escapedToChar,
                                                   parseEscaped)

import           Waargonaut.Types.JChar.Unescaped (AsUnescaped (..), Unescaped,
                                                   parseUnescaped)

-- $setup
-- >>> :set -XOverloadedStrings
-- >>> import Data.Function (($))
-- >>> import Data.Either(Either (..), isLeft)
-- >>> import Data.Digit (HeXDigit(..))
-- >>> import Utils
-- >>> import Waargonaut.Decode.Error (DecodeError)
-- >>> import Waargonaut.Types.Whitespace
-- >>> import Waargonaut.Types.JChar.Unescaped
-- >>> import Waargonaut.Types.JChar.Escaped
-- >>> import Waargonaut.Types.JChar
----

-- | A JChar may be unescaped or escaped.
data JChar digit
  = EscapedJChar ( Escaped digit )
  | UnescapedJChar Unescaped
  deriving (JChar digit -> JChar digit -> Bool
(JChar digit -> JChar digit -> Bool)
-> (JChar digit -> JChar digit -> Bool) -> Eq (JChar digit)
forall digit. Eq digit => JChar digit -> JChar digit -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JChar digit -> JChar digit -> Bool
$c/= :: forall digit. Eq digit => JChar digit -> JChar digit -> Bool
== :: JChar digit -> JChar digit -> Bool
$c== :: forall digit. Eq digit => JChar digit -> JChar digit -> Bool
Eq, Eq (JChar digit)
Eq (JChar digit)
-> (JChar digit -> JChar digit -> Ordering)
-> (JChar digit -> JChar digit -> Bool)
-> (JChar digit -> JChar digit -> Bool)
-> (JChar digit -> JChar digit -> Bool)
-> (JChar digit -> JChar digit -> Bool)
-> (JChar digit -> JChar digit -> JChar digit)
-> (JChar digit -> JChar digit -> JChar digit)
-> Ord (JChar digit)
JChar digit -> JChar digit -> Bool
JChar digit -> JChar digit -> Ordering
JChar digit -> JChar digit -> JChar digit
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall digit. Ord digit => Eq (JChar digit)
forall digit. Ord digit => JChar digit -> JChar digit -> Bool
forall digit. Ord digit => JChar digit -> JChar digit -> Ordering
forall digit.
Ord digit =>
JChar digit -> JChar digit -> JChar digit
min :: JChar digit -> JChar digit -> JChar digit
$cmin :: forall digit.
Ord digit =>
JChar digit -> JChar digit -> JChar digit
max :: JChar digit -> JChar digit -> JChar digit
$cmax :: forall digit.
Ord digit =>
JChar digit -> JChar digit -> JChar digit
>= :: JChar digit -> JChar digit -> Bool
$c>= :: forall digit. Ord digit => JChar digit -> JChar digit -> Bool
> :: JChar digit -> JChar digit -> Bool
$c> :: forall digit. Ord digit => JChar digit -> JChar digit -> Bool
<= :: JChar digit -> JChar digit -> Bool
$c<= :: forall digit. Ord digit => JChar digit -> JChar digit -> Bool
< :: JChar digit -> JChar digit -> Bool
$c< :: forall digit. Ord digit => JChar digit -> JChar digit -> Bool
compare :: JChar digit -> JChar digit -> Ordering
$ccompare :: forall digit. Ord digit => JChar digit -> JChar digit -> Ordering
$cp1Ord :: forall digit. Ord digit => Eq (JChar digit)
Ord, Int -> JChar digit -> ShowS
[JChar digit] -> ShowS
JChar digit -> String
(Int -> JChar digit -> ShowS)
-> (JChar digit -> String)
-> ([JChar digit] -> ShowS)
-> Show (JChar digit)
forall digit. Show digit => Int -> JChar digit -> ShowS
forall digit. Show digit => [JChar digit] -> ShowS
forall digit. Show digit => JChar digit -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JChar digit] -> ShowS
$cshowList :: forall digit. Show digit => [JChar digit] -> ShowS
show :: JChar digit -> String
$cshow :: forall digit. Show digit => JChar digit -> String
showsPrec :: Int -> JChar digit -> ShowS
$cshowsPrec :: forall digit. Show digit => Int -> JChar digit -> ShowS
Show, a -> JChar b -> JChar a
(a -> b) -> JChar a -> JChar b
(forall a b. (a -> b) -> JChar a -> JChar b)
-> (forall a b. a -> JChar b -> JChar a) -> Functor JChar
forall a b. a -> JChar b -> JChar a
forall a b. (a -> b) -> JChar a -> JChar b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> JChar b -> JChar a
$c<$ :: forall a b. a -> JChar b -> JChar a
fmap :: (a -> b) -> JChar a -> JChar b
$cfmap :: forall a b. (a -> b) -> JChar a -> JChar b
Functor, JChar a -> Bool
(a -> m) -> JChar a -> m
(a -> b -> b) -> b -> JChar a -> b
(forall m. Monoid m => JChar m -> m)
-> (forall m a. Monoid m => (a -> m) -> JChar a -> m)
-> (forall m a. Monoid m => (a -> m) -> JChar a -> m)
-> (forall a b. (a -> b -> b) -> b -> JChar a -> b)
-> (forall a b. (a -> b -> b) -> b -> JChar a -> b)
-> (forall b a. (b -> a -> b) -> b -> JChar a -> b)
-> (forall b a. (b -> a -> b) -> b -> JChar a -> b)
-> (forall a. (a -> a -> a) -> JChar a -> a)
-> (forall a. (a -> a -> a) -> JChar a -> a)
-> (forall a. JChar a -> [a])
-> (forall a. JChar a -> Bool)
-> (forall a. JChar a -> Int)
-> (forall a. Eq a => a -> JChar a -> Bool)
-> (forall a. Ord a => JChar a -> a)
-> (forall a. Ord a => JChar a -> a)
-> (forall a. Num a => JChar a -> a)
-> (forall a. Num a => JChar a -> a)
-> Foldable JChar
forall a. Eq a => a -> JChar a -> Bool
forall a. Num a => JChar a -> a
forall a. Ord a => JChar a -> a
forall m. Monoid m => JChar m -> m
forall a. JChar a -> Bool
forall a. JChar a -> Int
forall a. JChar a -> [a]
forall a. (a -> a -> a) -> JChar a -> a
forall m a. Monoid m => (a -> m) -> JChar a -> m
forall b a. (b -> a -> b) -> b -> JChar a -> b
forall a b. (a -> b -> b) -> b -> JChar a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: JChar a -> a
$cproduct :: forall a. Num a => JChar a -> a
sum :: JChar a -> a
$csum :: forall a. Num a => JChar a -> a
minimum :: JChar a -> a
$cminimum :: forall a. Ord a => JChar a -> a
maximum :: JChar a -> a
$cmaximum :: forall a. Ord a => JChar a -> a
elem :: a -> JChar a -> Bool
$celem :: forall a. Eq a => a -> JChar a -> Bool
length :: JChar a -> Int
$clength :: forall a. JChar a -> Int
null :: JChar a -> Bool
$cnull :: forall a. JChar a -> Bool
toList :: JChar a -> [a]
$ctoList :: forall a. JChar a -> [a]
foldl1 :: (a -> a -> a) -> JChar a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> JChar a -> a
foldr1 :: (a -> a -> a) -> JChar a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> JChar a -> a
foldl' :: (b -> a -> b) -> b -> JChar a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> JChar a -> b
foldl :: (b -> a -> b) -> b -> JChar a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> JChar a -> b
foldr' :: (a -> b -> b) -> b -> JChar a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> JChar a -> b
foldr :: (a -> b -> b) -> b -> JChar a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> JChar a -> b
foldMap' :: (a -> m) -> JChar a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> JChar a -> m
foldMap :: (a -> m) -> JChar a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> JChar a -> m
fold :: JChar m -> m
$cfold :: forall m. Monoid m => JChar m -> m
Foldable, Functor JChar
Foldable JChar
Functor JChar
-> Foldable JChar
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> JChar a -> f (JChar b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    JChar (f a) -> f (JChar a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> JChar a -> m (JChar b))
-> (forall (m :: * -> *) a. Monad m => JChar (m a) -> m (JChar a))
-> Traversable JChar
(a -> f b) -> JChar a -> f (JChar b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => JChar (m a) -> m (JChar a)
forall (f :: * -> *) a. Applicative f => JChar (f a) -> f (JChar a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> JChar a -> m (JChar b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> JChar a -> f (JChar b)
sequence :: JChar (m a) -> m (JChar a)
$csequence :: forall (m :: * -> *) a. Monad m => JChar (m a) -> m (JChar a)
mapM :: (a -> m b) -> JChar a -> m (JChar b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> JChar a -> m (JChar b)
sequenceA :: JChar (f a) -> f (JChar a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => JChar (f a) -> f (JChar a)
traverse :: (a -> f b) -> JChar a -> f (JChar b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> JChar a -> f (JChar b)
$cp2Traversable :: Foldable JChar
$cp1Traversable :: Functor JChar
Traversable)

-- | Typeclass for things that have a 'JChar'.
class HasJChar c digit | c -> digit where
  jChar :: Lens' c (JChar digit)

instance HasJChar (JChar digit) digit where
  jChar :: (JChar digit -> f (JChar digit)) -> JChar digit -> f (JChar digit)
jChar = (JChar digit -> f (JChar digit)) -> JChar digit -> f (JChar digit)
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id

-- | Typeclass for things that be used as a 'JChar'.
class AsJChar r digit | r -> digit where
  _JChar          :: Prism' r (JChar digit)
  _EscapedJChar   :: Prism' r (Escaped digit)
  _UnescapedJChar :: Prism' r Unescaped

  _EscapedJChar   = p (JChar digit) (f (JChar digit)) -> p r (f r)
forall r digit. AsJChar r digit => Prism' r (JChar digit)
_JChar (p (JChar digit) (f (JChar digit)) -> p r (f r))
-> (p (Escaped digit) (f (Escaped digit))
    -> p (JChar digit) (f (JChar digit)))
-> p (Escaped digit) (f (Escaped digit))
-> p r (f r)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. p (Escaped digit) (f (Escaped digit))
-> p (JChar digit) (f (JChar digit))
forall r digit. AsJChar r digit => Prism' r (Escaped digit)
_EscapedJChar
  _UnescapedJChar = p (JChar digit) (f (JChar digit)) -> p r (f r)
forall r digit. AsJChar r digit => Prism' r (JChar digit)
_JChar (p (JChar digit) (f (JChar digit)) -> p r (f r))
-> (p Unescaped (f Unescaped) -> p (JChar digit) (f (JChar digit)))
-> p Unescaped (f Unescaped)
-> p r (f r)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. p Unescaped (f Unescaped) -> p (JChar digit) (f (JChar digit))
forall r digit. AsJChar r digit => Prism' r Unescaped
_UnescapedJChar

instance AsJChar (JChar digit) digit where
  _JChar :: p (JChar digit) (f (JChar digit))
-> p (JChar digit) (f (JChar digit))
_JChar = p (JChar digit) (f (JChar digit))
-> p (JChar digit) (f (JChar digit))
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  _EscapedJChar :: p (Escaped digit) (f (Escaped digit))
-> p (JChar digit) (f (JChar digit))
_EscapedJChar = (Escaped digit -> JChar digit)
-> (JChar digit -> Either (JChar digit) (Escaped digit))
-> Prism' (JChar digit) (Escaped digit)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism Escaped digit -> JChar digit
forall digit. Escaped digit -> JChar digit
EscapedJChar
    (\ JChar digit
x -> case JChar digit
x of
        EscapedJChar Escaped digit
y1 -> Escaped digit -> Either (JChar digit) (Escaped digit)
forall a b. b -> Either a b
Right Escaped digit
y1
        JChar digit
_               -> JChar digit -> Either (JChar digit) (Escaped digit)
forall a b. a -> Either a b
Left JChar digit
x
    )
  _UnescapedJChar :: p Unescaped (f Unescaped) -> p (JChar digit) (f (JChar digit))
_UnescapedJChar = (Unescaped -> JChar digit)
-> (JChar digit -> Either (JChar digit) Unescaped)
-> Prism' (JChar digit) Unescaped
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism Unescaped -> JChar digit
forall digit. Unescaped -> JChar digit
UnescapedJChar
    (\ JChar digit
x -> case JChar digit
x of
        UnescapedJChar Unescaped
y1 -> Unescaped -> Either (JChar digit) Unescaped
forall a b. b -> Either a b
Right Unescaped
y1
        JChar digit
_                 -> JChar digit -> Either (JChar digit) Unescaped
forall a b. a -> Either a b
Left JChar digit
x
    )

instance AsEscaped (JChar digit) digit where
  _Escaped :: p (Escaped digit) (f (Escaped digit))
-> p (JChar digit) (f (JChar digit))
_Escaped = p (JChar digit) (f (JChar digit))
-> p (JChar digit) (f (JChar digit))
forall r digit. AsJChar r digit => Prism' r (JChar digit)
_JChar (p (JChar digit) (f (JChar digit))
 -> p (JChar digit) (f (JChar digit)))
-> (p (Escaped digit) (f (Escaped digit))
    -> p (JChar digit) (f (JChar digit)))
-> p (Escaped digit) (f (Escaped digit))
-> p (JChar digit) (f (JChar digit))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. p (Escaped digit) (f (Escaped digit))
-> p (JChar digit) (f (JChar digit))
forall r digit. AsEscaped r digit => Prism' r (Escaped digit)
_Escaped

instance AsUnescaped (JChar digit) where
  _Unescaped :: p Unescaped (f Unescaped) -> p (JChar digit) (f (JChar digit))
_Unescaped = p (JChar digit) (f (JChar digit))
-> p (JChar digit) (f (JChar digit))
forall r digit. AsJChar r digit => Prism' r (JChar digit)
_JChar (p (JChar digit) (f (JChar digit))
 -> p (JChar digit) (f (JChar digit)))
-> (p Unescaped (f Unescaped) -> p (JChar digit) (f (JChar digit)))
-> p Unescaped (f Unescaped)
-> p (JChar digit) (f (JChar digit))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. p Unescaped (f Unescaped) -> p (JChar digit) (f (JChar digit))
forall a. AsUnescaped a => Prism' a Unescaped
_Unescaped

-- instance AsJChar Char HeXDigit where
-- Don't implement this, it's not a lawful prism.

-- | Convert a 'JChar' to a Haskell 'Char'
jCharToChar :: JChar HeXDigit -> Char
jCharToChar :: JChar HeXDigit -> Char
jCharToChar (UnescapedJChar Unescaped
uejc) = 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
uejc
jCharToChar (EscapedJChar Escaped HeXDigit
ejc)    = Escaped HeXDigit -> Char
escapedToChar Escaped HeXDigit
ejc

-- | Attempt to convert a Haskell 'Char' to a JSON acceptable 'JChar'
charToJChar :: Char -> Maybe (JChar HeXDigit)
charToJChar :: Char -> Maybe (JChar HeXDigit)
charToJChar Char
c =
  (Unescaped -> JChar HeXDigit
forall digit. Unescaped -> JChar digit
UnescapedJChar (Unescaped -> JChar HeXDigit)
-> Maybe Unescaped -> Maybe (JChar HeXDigit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting (First Unescaped) Char Unescaped -> Char -> Maybe Unescaped
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview Getting (First Unescaped) Char Unescaped
forall a. AsUnescaped a => Prism' a Unescaped
_Unescaped Char
c) Maybe (JChar HeXDigit)
-> Maybe (JChar HeXDigit) -> Maybe (JChar HeXDigit)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (Escaped HeXDigit -> JChar HeXDigit
forall digit. Escaped digit -> JChar digit
EscapedJChar (Escaped HeXDigit -> JChar HeXDigit)
-> Maybe (Escaped HeXDigit) -> Maybe (JChar HeXDigit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> Maybe (Escaped HeXDigit)
charToEscaped Char
c)

utf8SafeChar :: Char -> Maybe Char
utf8SafeChar :: Char -> Maybe Char
utf8SafeChar Char
c | Char -> Int
ord Char
c Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x1ff800 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0xd800 = Char -> Maybe Char
forall a. a -> Maybe a
Just Char
c
               | Bool
otherwise                    = Maybe Char
forall a. Maybe a
Nothing

-- | Convert a 'Char' to 'JChar HexDigit' and replace any invalid values with
-- @U+FFFD@ as per the 'Data.Text.Text' documentation.
--
-- Refer to <https://hackage.haskell.org/package/text/docs/Data-Text.html#g:2 'Text'> documentation for more info.
--
utf8CharToJChar :: Char -> JChar HeXDigit
utf8CharToJChar :: Char -> JChar HeXDigit
utf8CharToJChar Char
c = JChar HeXDigit -> Maybe (JChar HeXDigit) -> JChar HeXDigit
forall a. a -> Maybe a -> a
fromMaybe JChar HeXDigit
scalarReplacement (Char -> Maybe (JChar HeXDigit)
charToJChar (Char -> Maybe (JChar HeXDigit)) -> Char -> Maybe (JChar HeXDigit)
forall a b. (a -> b) -> a -> b
$ Char -> Char
Text.safe Char
c)
  where scalarReplacement :: JChar HeXDigit
scalarReplacement = Escaped HeXDigit -> JChar HeXDigit
forall digit. Escaped digit -> JChar digit
EscapedJChar (HexDigit4 HeXDigit -> Escaped HeXDigit
forall digit. HexDigit4 digit -> Escaped digit
Hex (HeXDigit -> HeXDigit -> HeXDigit -> HeXDigit -> HexDigit4 HeXDigit
forall d. d -> d -> d -> d -> HexDigit4 d
HexDigit4 HeXDigit
forall d. Df d => d
D.xf HeXDigit
forall d. Df d => d
D.xf HeXDigit
forall d. Df d => d
D.xf HeXDigit
forall d. Dd d => d
D.xd))
{-# INLINE utf8CharToJChar #-}

-- | Try to convert a 'JChar' to a 'Data.Text.Text' safe 'Char' value. Refer to the link for more info:
-- https://hackage.haskell.org/package/text-1.2.3.0/docs/Data-Text-Internal.html#v:safe
jCharToUtf8Char :: JChar HeXDigit -> Maybe Char
jCharToUtf8Char :: JChar HeXDigit -> Maybe Char
jCharToUtf8Char = Char -> Maybe Char
utf8SafeChar (Char -> Maybe Char)
-> (JChar HeXDigit -> Char) -> JChar HeXDigit -> Maybe Char
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. JChar HeXDigit -> Char
jCharToChar
{-# INLINE jCharToUtf8Char #-}

-- | Parse a JSON character.
--
-- >>> testparse parseJChar "\\u1234" :: Either DecodeError (JChar HeXDigit)
-- Right (EscapedJChar (Hex (HexDigit4 HeXDigit1 HeXDigit2 HeXDigit3 HeXDigit4)))
--
-- >>> testparse parseJChar "\\\\" :: Either DecodeError (JChar HeXDigit)
-- Right (EscapedJChar ReverseSolidus)
--
-- >>> testparse parseJChar "\\r"
-- Right (EscapedJChar (WhiteSpace CarriageReturn))
--
-- >>> testparsetheneof parseJChar "a"
-- Right (UnescapedJChar (Unescaped 'a'))
--
-- >>> testparsethennoteof parseJChar "ax"
-- Right (UnescapedJChar (Unescaped 'a'))
parseJChar ::
  (CharParsing f, HeXaDeCiMaL digit) =>
  f ( JChar digit )
parseJChar :: f (JChar digit)
parseJChar = [f (JChar digit)] -> f (JChar digit)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum
  [ Escaped digit -> JChar digit
forall digit. Escaped digit -> JChar digit
EscapedJChar (Escaped digit -> JChar digit)
-> f (Escaped digit) -> f (JChar digit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (Escaped digit)
forall (f :: * -> *) digit.
(CharParsing f, HeXaDeCiMaL digit) =>
f (Escaped digit)
parseEscaped
  , Unescaped -> JChar digit
forall digit. Unescaped -> JChar digit
UnescapedJChar (Unescaped -> JChar digit) -> f Unescaped -> f (JChar digit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f Unescaped
forall (f :: * -> *). CharParsing f => f Unescaped
parseUnescaped
  ]