{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Waargonaut.Types.JChar.HexDigit4
(
HexDigit4 (..)
, HasHexDigit4 (..)
, parseHexDigit4
, hexDigit4ToChar
, charToHexDigit4
) where
import Prelude (Eq, Ord (..), Show, otherwise, (||))
import Control.Applicative ((<*>))
import Control.Category (id, (.))
import Control.Lens (Lens')
import Control.Monad ((=<<))
import Control.Error.Util (hush)
import Data.List.NonEmpty (NonEmpty ((:|)))
import Data.Foldable (Foldable)
import Data.Function (($))
import Data.Functor (Functor, fmap, (<$>))
import Data.Traversable (Traversable)
import Data.Char (Char, chr, ord)
import Data.Either (Either (..))
import Data.Maybe (Maybe (..))
import Text.Parser.Char (CharParsing)
import Data.Digit (HeXDigit, HeXaDeCiMaL)
import qualified Data.Digit as D
data HexDigit4 d =
HexDigit4 d d d d
deriving (Eq, Show, Ord, Functor, Foldable, Traversable)
class HasHexDigit4 c d | c -> d where
hexDigit4 :: Lens' c (HexDigit4 d)
instance HasHexDigit4 (HexDigit4 d) d where
hexDigit4 = id
hexHeX :: D.HexDigit -> D.HeXDigit
hexHeX = \case
D.HexDigit0 -> D.HeXDigit0
D.HexDigit1 -> D.HeXDigit1
D.HexDigit2 -> D.HeXDigit2
D.HexDigit3 -> D.HeXDigit3
D.HexDigit4 -> D.HeXDigit4
D.HexDigit5 -> D.HeXDigit5
D.HexDigit6 -> D.HeXDigit6
D.HexDigit7 -> D.HeXDigit7
D.HexDigit8 -> D.HeXDigit8
D.HexDigit9 -> D.HeXDigit9
D.HexDigita -> D.HeXDigita
D.HexDigitb -> D.HeXDigitb
D.HexDigitc -> D.HeXDigitc
D.HexDigitd -> D.HeXDigitd
D.HexDigite -> D.HeXDigite
D.HexDigitf -> D.HeXDigitf
hexDigit4ToChar :: HexDigit4 HeXDigit -> Char
hexDigit4ToChar (HexDigit4 a b c d) = chr (D._HeXDigitsIntegral (Right $ a :| [b,c,d]))
charToHexDigit4 :: Char -> Maybe (HexDigit4 HeXDigit)
charToHexDigit4 x
| x < '\x0' || x > '\xffff' = Nothing
| otherwise = toHexDig . fmap hexHeX =<< hush (D.integralHexDigits (ord x))
where
z = D.x0
toHexDig (a :| [b,c,d]) = Just (HexDigit4 a b c d)
toHexDig ( b :| [c,d]) = Just (HexDigit4 z b c d)
toHexDig ( c :| [d]) = Just (HexDigit4 z z c d)
toHexDig ( d :| []) = Just (HexDigit4 z z z d)
toHexDig _ = Nothing
{-# INLINE charToHexDigit4 #-}
parseHexDigit4 ::
( CharParsing f, HeXaDeCiMaL digit ) =>
f ( HexDigit4 digit )
parseHexDigit4 = HexDigit4
<$> D.parseHeXaDeCiMaL
<*> D.parseHeXaDeCiMaL
<*> D.parseHeXaDeCiMaL
<*> D.parseHeXaDeCiMaL