{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
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
data CharOutOfRange = CharOutOfRange Int Char deriving (Eq, Show)
instance Encode (Either EncodeEx) "r-ByteRep" "r-ByteRep" c Char where
encoding = encByteChar
instance Encode (Either EncodeEx) "r-ByteRep" "r-ByteRep" c B.ByteString where
encoding = encByteRepB
instance Encode (Either EncodeEx) "r-ByteRep" "r-ByteRep" c BL.ByteString where
encoding = encByteRepBL
instance Encode (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String where
encoding = encByteRepS
encByteChar :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c Char
encByteChar = _implEncodingEx (\c -> explainBool (CharOutOfRange 255) (c, (> 255) . ord $ c))
encByteRepB :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c B.ByteString
encByteRepB = _implEncodingEx @"r-ByteRep" (encImpl 255)
encByteRepBL :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c BL.ByteString
encByteRepBL = _implEncodingEx @"r-ByteRep" (encImpl 255)
encByteRepS :: Encoding (Either EncodeEx) "r-ByteRep" "r-ByteRep" c String
encByteRepS = _implEncodingEx @"r-ByteRep" (encImpl 255)
instance (RecreateErr f, Applicative f) => Validate f "r-ByteRep" "r-ByteRep" () B.ByteString where
validation = validR encByteRepB
instance (RecreateErr f, Applicative f) => Validate f "r-ByteRep" "r-ByteRep" () BL.ByteString where
validation = validR encByteRepBL
instance (RecreateErr f, Applicative f) => Validate f "r-ByteRep" "r-ByteRep" () String where
validation = validR encByteRepS
encImpl :: Char8Find str => Int -> str -> Either CharOutOfRange str
encImpl bound str = case find ((> bound) . ord) str of
Nothing -> Right str
Just ch -> Left $ CharOutOfRange bound ch