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

-- | 
-- Convenience validation utilities.
module Data.TypedEncoding.Instances.Support.Validate where
import           Data.TypedEncoding.Common.Types
import           Data.TypedEncoding.Common.Class 

import           GHC.TypeLits
import           Data.Proxy

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


-- * Validation

-- |
-- @since 0.3.0.0
validFromDec :: forall nm f c str . (KnownSymbol nm, RecreateErr f, Applicative f) => Decoding (Either UnexpectedDecodeEx) nm nm c str -> Validation f nm nm c str  
validFromDec :: Decoding (Either UnexpectedDecodeEx) nm nm c str
-> Validation f nm nm c str
validFromDec = forall (alg :: Symbol) (nm :: Symbol) (f :: * -> *) c str.
(KnownSymbol nm, RecreateErr @* f, Applicative f) =>
Decoding (Either UnexpectedDecodeEx) nm alg c str
-> Validation f nm alg c str
forall (f :: * -> *) c str.
(KnownSymbol nm, RecreateErr @* f, Applicative f) =>
Decoding (Either UnexpectedDecodeEx) nm nm c str
-> Validation f nm nm c str
validFromDec' @nm @nm 

-- |
-- @since 0.3.0.0
validFromDec' :: forall alg nm f c str . (KnownSymbol nm, RecreateErr f, Applicative f) => Decoding (Either UnexpectedDecodeEx) nm alg c str -> Validation f nm alg c str  
validFromDec' :: Decoding (Either UnexpectedDecodeEx) nm alg c str
-> Validation f nm alg c str
validFromDec' (UnsafeMkDecoding Proxy @Symbol nm
p forall (xs :: [Symbol]).
Enc @[Symbol] ((':) @Symbol nm xs) c str
-> Either UnexpectedDecodeEx (Enc @[Symbol] xs c str)
fn) = Proxy @Symbol nm
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) c str
    -> f (Enc @[Symbol] xs c str))
-> Validation f nm alg c str
forall (nm :: Symbol) conf str (f :: * -> *) (alg :: Symbol).
Proxy @Symbol nm
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) conf str
    -> f (Enc @[Symbol] xs conf str))
-> Validation f nm alg conf str
UnsafeMkValidation Proxy @Symbol nm
p (Either UnexpectedDecodeEx (Enc @[Symbol] xs c str)
-> f (Enc @[Symbol] xs c str)
forall a. Either UnexpectedDecodeEx a -> f a
decAsRecreateErr (Either UnexpectedDecodeEx (Enc @[Symbol] xs c str)
 -> f (Enc @[Symbol] xs c str))
-> (Enc @[Symbol] ((':) @Symbol nm xs) c str
    -> Either UnexpectedDecodeEx (Enc @[Symbol] xs c str))
-> Enc @[Symbol] ((':) @Symbol nm xs) c str
-> f (Enc @[Symbol] xs c str)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Enc @[Symbol] ((':) @Symbol nm xs) c str
-> Either UnexpectedDecodeEx (Enc @[Symbol] xs c str)
forall (xs :: [Symbol]).
Enc @[Symbol] ((':) @Symbol nm xs) c str
-> Either UnexpectedDecodeEx (Enc @[Symbol] xs c str)
fn)
   where 
        decAsRecreateErr :: Either UnexpectedDecodeEx a -> f a
        decAsRecreateErr :: Either UnexpectedDecodeEx a -> f a
decAsRecreateErr (Left (UnexpectedDecodeEx Proxy @Symbol x
p a
err)) = RecreateEx -> f a
forall k (f :: k -> *) (a :: k).
RecreateErr @k f =>
RecreateEx -> f a
recoveryErr (RecreateEx -> f a) -> RecreateEx -> f a
forall a b. (a -> b) -> a -> b
$ Proxy @Symbol x -> a -> RecreateEx
forall e (x :: Symbol).
(Show e, KnownSymbol x) =>
Proxy @Symbol x -> e -> RecreateEx
RecreateEx Proxy @Symbol x
p a
err
        decAsRecreateErr (Right a
r) = a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
r

-- |
-- @since 0.3.0.0
validR :: forall nm 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) nm nm c str -> Validation f nm nm c str
validR = forall (alg :: Symbol) (nm :: Symbol) (f :: * -> *) c str.
(KnownSymbol nm, RecreateErr @* f, Applicative f) =>
Encoding (Either EncodeEx) nm alg c str
-> Validation f nm alg c str
forall (f :: * -> *) c str.
(KnownSymbol nm, RecreateErr @* f, Applicative f) =>
Encoding (Either EncodeEx) nm nm c str -> Validation f nm nm c str
validRFromEnc' @nm @nm 


-- | Can cause slow compilation if used
--
-- (renamed from validR defined in pre 0.5 versions)
--
-- @since 0.5.0.0
_validR :: forall nm f c str alg . (Restriction nm, Algorithm nm alg, KnownSymbol nm, RecreateErr f, Applicative f) =>  Encoding (Either EncodeEx) nm alg c str -> Validation f nm alg c str  
_validR :: Encoding (Either EncodeEx) nm alg c str
-> Validation f nm alg c str
_validR = forall (alg :: Symbol) (nm :: Symbol) (f :: * -> *) c str.
(KnownSymbol nm, RecreateErr @* f, Applicative f) =>
Encoding (Either EncodeEx) nm alg c str
-> Validation f nm alg c str
forall (f :: * -> *) c str.
(KnownSymbol nm, RecreateErr @* f, Applicative f) =>
Encoding (Either EncodeEx) nm alg c str
-> Validation f nm alg c str
validRFromEnc' @alg @nm 


-- |
-- This should be used with "r-" validations only
--
-- @since 0.3.0.0
validFromEnc' :: forall alg nm f c str . (KnownSymbol nm, RecreateErr f, Applicative f) => Encoding (Either EncodeEx) nm alg c str -> Validation f nm alg c str  
validFromEnc' :: Encoding (Either EncodeEx) nm alg c str
-> Validation f nm alg c str
validFromEnc' = Encoding (Either EncodeEx) nm alg c str
-> Validation f nm alg c str
forall (alg :: Symbol) (nm :: Symbol) (f :: * -> *) c str.
(KnownSymbol nm, RecreateErr @* f, Applicative f) =>
Encoding (Either EncodeEx) nm alg c str
-> Validation f nm alg c str
validRFromEnc'
 

{-# DEPRECATED validFromEnc' "Use _validR instead (valid for r- encodings only)" #-}


validRFromEnc' :: forall alg nm f c str . (KnownSymbol nm, RecreateErr f, Applicative f) => Encoding (Either EncodeEx) nm alg c str -> Validation f nm alg c str  
validRFromEnc' :: Encoding (Either EncodeEx) nm alg c str
-> Validation f nm alg c str
validRFromEnc' (UnsafeMkEncoding Proxy @Symbol nm
p forall (xs :: [Symbol]).
Enc @[Symbol] xs c str
-> Either EncodeEx (Enc @[Symbol] ((':) @Symbol nm xs) c str)
fn) = Proxy @Symbol nm
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) c str
    -> f (Enc @[Symbol] xs c str))
-> Validation f nm alg c str
forall (nm :: Symbol) conf str (f :: * -> *) (alg :: Symbol).
Proxy @Symbol nm
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) conf str
    -> f (Enc @[Symbol] xs conf str))
-> Validation f nm alg conf str
UnsafeMkValidation Proxy @Symbol nm
p (Either EncodeEx (Enc @[Symbol] xs c str)
-> f (Enc @[Symbol] xs c str)
forall a. Either EncodeEx a -> f a
encAsRecreateErr (Either EncodeEx (Enc @[Symbol] xs c str)
 -> f (Enc @[Symbol] xs c str))
-> (Enc @[Symbol] ((':) @Symbol nm xs) c str
    -> Either EncodeEx (Enc @[Symbol] xs c str))
-> Enc @[Symbol] ((':) @Symbol nm xs) c str
-> f (Enc @[Symbol] xs c str)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Enc @[Symbol] ((':) @Symbol nm xs) c str
-> Either EncodeEx (Enc @[Symbol] xs c str)
forall (xs :: [Symbol]).
Enc @[Symbol] ((':) @Symbol nm xs) c str
-> Either EncodeEx (Enc @[Symbol] xs c str)
rfn) 
   where
        encAsRecreateErr :: Either EncodeEx a -> f a
        encAsRecreateErr :: Either EncodeEx a -> f a
encAsRecreateErr (Left (EncodeEx Proxy @Symbol x
p a
err)) = RecreateEx -> f a
forall k (f :: k -> *) (a :: k).
RecreateErr @k f =>
RecreateEx -> f a
recoveryErr (RecreateEx -> f a) -> RecreateEx -> f a
forall a b. (a -> b) -> a -> b
$ Proxy @Symbol x -> a -> RecreateEx
forall e (x :: Symbol).
(Show e, KnownSymbol x) =>
Proxy @Symbol x -> e -> RecreateEx
RecreateEx Proxy @Symbol x
p a
err
        encAsRecreateErr (Right a
r) = a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
r 
        rfn :: forall (xs :: [Symbol]) . Enc (nm ': xs) c str -> Either EncodeEx (Enc xs c str)
        rfn :: Enc @[Symbol] ((':) @Symbol nm xs) c str
-> Either EncodeEx (Enc @[Symbol] xs c str)
rfn (UnsafeMkEnc Proxy @[Symbol] ((':) @Symbol nm xs)
_ c
conf str
str)  =    
            let re :: Either
  EncodeEx (Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str)
re = Enc @[Symbol] (Any @[Symbol]) c str
-> Either
     EncodeEx (Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str)
forall (xs :: [Symbol]).
Enc @[Symbol] xs c str
-> Either EncodeEx (Enc @[Symbol] ((':) @Symbol nm xs) c str)
fn (Enc @[Symbol] (Any @[Symbol]) c str
 -> Either
      EncodeEx (Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str))
-> Enc @[Symbol] (Any @[Symbol]) c str
-> Either
     EncodeEx (Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str)
forall a b. (a -> b) -> a -> b
$ Proxy @[Symbol] (Any @[Symbol])
-> c -> str -> Enc @[Symbol] (Any @[Symbol]) c str
forall k (nms :: k) conf str.
Proxy @k nms -> conf -> str -> Enc @k nms conf str
UnsafeMkEnc Proxy @[Symbol] (Any @[Symbol])
forall k (t :: k). Proxy @k t
Proxy c
conf str
str
            in  Proxy @[Symbol] xs -> c -> str -> Enc @[Symbol] xs c str
forall k (nms :: k) conf str.
Proxy @k nms -> conf -> str -> Enc @k nms conf str
UnsafeMkEnc Proxy @[Symbol] xs
forall k (t :: k). Proxy @k t
Proxy c
conf (str -> Enc @[Symbol] xs c str)
-> (Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str -> str)
-> Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str
-> Enc @[Symbol] xs c str
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str -> str
forall k (enc :: k) conf str. Enc @k enc conf str -> str
getPayload (Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str
 -> Enc @[Symbol] xs c str)
-> Either
     EncodeEx (Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str)
-> Either EncodeEx (Enc @[Symbol] xs c str)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either
  EncodeEx (Enc @[Symbol] ((':) @Symbol nm (Any @[Symbol])) c str)
re