{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}

-- | 
-- @"r-ByteRep"@ represents Characters used for Byte representations.
--
-- It is common to use @Char@ instead of @Word8@ when low level programming on @ByteString@.
--
-- This annotation represents such use of string characters.
-- 
-- Checks if all chars are @< \'\256\'@
--
-- Currently, this should be not used as superset 'Data.TypedEncoding.Common.Class.Superset.IsSuperset'
--
-- It is subset of "r-CHAR8":
--
-- @Superset "r-CHAR8" ""r-ByteRep"    
--
-- Currently, is (intentionally not decodable)
--
-- @since 0.3.1.0
module Data.TypedEncoding.Instances.Restriction.ByteRep where

import           Data.TypedEncoding.Instances.Support
import           Data.TypedEncoding.Common.Class.Util.StringConstraints

import           Data.TypedEncoding.Internal.Util (explainBool)
import           Data.Char

import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL

-- $setup
-- >>> :set -XDataKinds -XTypeApplications


-----------------
-- Encodings  --
-----------------

data CharOutOfRange = CharOutOfRange Int Char deriving (CharOutOfRange -> CharOutOfRange -> Bool
(CharOutOfRange -> CharOutOfRange -> Bool)
-> (CharOutOfRange -> CharOutOfRange -> Bool) -> Eq CharOutOfRange
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CharOutOfRange -> CharOutOfRange -> Bool
$c/= :: CharOutOfRange -> CharOutOfRange -> Bool
== :: CharOutOfRange -> CharOutOfRange -> Bool
$c== :: CharOutOfRange -> CharOutOfRange -> Bool
Eq, Int -> CharOutOfRange -> ShowS
[CharOutOfRange] -> ShowS
CharOutOfRange -> String
(Int -> CharOutOfRange -> ShowS)
-> (CharOutOfRange -> String)
-> ([CharOutOfRange] -> ShowS)
-> Show CharOutOfRange
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CharOutOfRange] -> ShowS
$cshowList :: [CharOutOfRange] -> ShowS
show :: CharOutOfRange -> String
$cshow :: CharOutOfRange -> String
showsPrec :: Int -> CharOutOfRange -> ShowS
$cshowsPrec :: Int -> CharOutOfRange -> ShowS
Show)

-- * Encoding @"r-ByteRep"@

instance Encode (Either EncodeEx) "r-ByteRep" "r-ByteRep" c Char where
    encoding :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c Char
encoding = Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c Char
forall c. Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c Char
encByteChar    

instance Encode (Either EncodeEx) "r-ByteRep" "r-ByteRep" c B.ByteString where
    encoding :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
encoding = Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
forall c.
Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
encByteRepB

instance Encode (Either EncodeEx) "r-ByteRep" "r-ByteRep" c BL.ByteString where
    encoding :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
encoding = Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
forall c.
Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
encByteRepBL

instance Encode (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String where
    encoding :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String
encoding = Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String
forall c.
Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String
encByteRepS

encByteChar :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c Char 
encByteChar :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c Char
encByteChar = (Char -> Either CharOutOfRange Char)
-> Encoding
     (Either EncodeEx) "r-ByteRep" (AlgNm "r-ByteRep") c Char
forall (nm :: Symbol) err c str.
(KnownSymbol nm, Show err) =>
(str -> Either err str)
-> Encoding (Either EncodeEx) nm (AlgNm nm) c str
_implEncodingEx (\Char
c -> (Char -> CharOutOfRange)
-> (Char, Bool) -> Either CharOutOfRange Char
forall a err. (a -> err) -> (a, Bool) -> Either err a
explainBool (Int -> Char -> CharOutOfRange
CharOutOfRange Int
255) (Char
c, (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
255) (Int -> Bool) -> (Char -> Int) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord (Char -> Bool) -> Char -> Bool
forall a b. (a -> b) -> a -> b
$ Char
c))    

encByteRepB :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c B.ByteString
encByteRepB :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
encByteRepB = (ByteString -> Either CharOutOfRange ByteString)
-> Encoding
     (Either EncodeEx) "r-ByteRep" (AlgNm "r-ByteRep") c ByteString
forall (nm :: Symbol) err c str.
(KnownSymbol nm, Show err) =>
(str -> Either err str)
-> Encoding (Either EncodeEx) nm (AlgNm nm) c str
_implEncodingEx @"r-ByteRep" (Int -> ByteString -> Either CharOutOfRange ByteString
forall str.
Char8Find str =>
Int -> str -> Either CharOutOfRange str
encImpl Int
255)

encByteRepBL :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c BL.ByteString
encByteRepBL :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
encByteRepBL = (ByteString -> Either CharOutOfRange ByteString)
-> Encoding
     (Either EncodeEx) "r-ByteRep" (AlgNm "r-ByteRep") c ByteString
forall (nm :: Symbol) err c str.
(KnownSymbol nm, Show err) =>
(str -> Either err str)
-> Encoding (Either EncodeEx) nm (AlgNm nm) c str
_implEncodingEx @"r-ByteRep" (Int -> ByteString -> Either CharOutOfRange ByteString
forall str.
Char8Find str =>
Int -> str -> Either CharOutOfRange str
encImpl Int
255)

encByteRepS :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String
encByteRepS :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String
encByteRepS = (String -> Either CharOutOfRange String)
-> Encoding
     (Either EncodeEx) "r-ByteRep" (AlgNm "r-ByteRep") c String
forall (nm :: Symbol) err c str.
(KnownSymbol nm, Show err) =>
(str -> Either err str)
-> Encoding (Either EncodeEx) nm (AlgNm nm) c str
_implEncodingEx @"r-ByteRep" (Int -> String -> Either CharOutOfRange String
forall str.
Char8Find str =>
Int -> str -> Either CharOutOfRange str
encImpl Int
255)


-- * Decoding @"r-ByteRep"@

-- instance (Applicative f) => Decode f "r-ByteRep" "r-ByteRep" c str where
--     decoding = decAnyR


instance (RecreateErr f, Applicative f) => Validate f "r-ByteRep" "r-ByteRep" () B.ByteString where
    validation :: Validation f "r-ByteRep" "r-ByteRep" () ByteString
validation = Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" () ByteString
-> Validation f "r-ByteRep" "r-ByteRep" () ByteString
forall (nm :: Symbol) (f :: * -> *) c str.
(Restriction nm, KnownSymbol nm, RecreateErr @* f,
 Applicative f) =>
Encoding (Either EncodeEx) nm nm c str -> Validation f nm nm c str
validR Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" () ByteString
forall c.
Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
encByteRepB

instance (RecreateErr f, Applicative f) => Validate f "r-ByteRep" "r-ByteRep" () BL.ByteString where
    validation :: Validation f "r-ByteRep" "r-ByteRep" () ByteString
validation = Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" () ByteString
-> Validation f "r-ByteRep" "r-ByteRep" () ByteString
forall (nm :: Symbol) (f :: * -> *) c str.
(Restriction nm, KnownSymbol nm, RecreateErr @* f,
 Applicative f) =>
Encoding (Either EncodeEx) nm nm c str -> Validation f nm nm c str
validR Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" () ByteString
forall c.
Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c ByteString
encByteRepBL

instance (RecreateErr f, Applicative f) => Validate f "r-ByteRep" "r-ByteRep" () String where
    validation :: Validation f "r-ByteRep" "r-ByteRep" () String
validation = Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" () String
-> Validation f "r-ByteRep" "r-ByteRep" () String
forall (nm :: Symbol) (f :: * -> *) c str.
(Restriction nm, KnownSymbol nm, RecreateErr @* f,
 Applicative f) =>
Encoding (Either EncodeEx) nm nm c str -> Validation f nm nm c str
validR Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" () String
forall c.
Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String
encByteRepS


-- * Implementation 

-- 255 for CHAR8 / "r-ByteRep"
encImpl :: Char8Find str => Int -> str -> Either CharOutOfRange str
encImpl :: Int -> str -> Either CharOutOfRange str
encImpl Int
bound str
str = case (Char -> Bool) -> str -> Maybe Char
forall str. Char8Find str => (Char -> Bool) -> str -> Maybe Char
find ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
bound) (Int -> Bool) -> (Char -> Int) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord) str
str of 
    Maybe Char
Nothing -> str -> Either CharOutOfRange str
forall a b. b -> Either a b
Right str
str
    Just Char
ch -> CharOutOfRange -> Either CharOutOfRange str
forall a b. a -> Either a b
Left (CharOutOfRange -> Either CharOutOfRange str)
-> CharOutOfRange -> Either CharOutOfRange str
forall a b. (a -> b) -> a -> b
$ Int -> Char -> CharOutOfRange
CharOutOfRange Int
bound Char
ch