{-# language DataKinds #-}
{-# language GADTs #-}
{-# language NamedFieldPuns #-}
{-# language StandaloneKindSignatures #-}
{-# language TypeFamilies #-}

module Rel8.Schema.Result
  ( Result
  , null, nullifier, unnullifier
  , vectorizer, unvectorizer
  )
where

-- base
import Data.Functor.Identity ( Identity( Identity), runIdentity )
import Prelude hiding ( null )

-- rel8
import Rel8.Schema.Kind ( Context )
import Rel8.Schema.Null ( Nullify, Nullity( Null, NotNull ) )
import Rel8.Schema.Spec ( Spec(..) )


-- | The @Result@ context is the context used for decoded query results.
--
-- When a query is executed against a PostgreSQL database, Rel8 parses the
-- returned rows, decoding each row into the @Result@ context.
type Result :: Context
type Result = Identity


null :: Result (Maybe a)
null :: forall a. Result (Maybe a)
null = forall a. a -> Identity a
Identity forall a. Maybe a
Nothing


nullifier :: Spec a -> Result a -> Result (Nullify a)
nullifier :: forall a. Spec a -> Result a -> Result (Nullify a)
nullifier Spec {Nullity a
nullity :: forall a. Spec a -> Nullity a
nullity :: Nullity a
nullity} (Identity a
a) = forall a. a -> Identity a
Identity forall a b. (a -> b) -> a -> b
$ case Nullity a
nullity of
  Nullity a
Null -> a
a
  Nullity a
NotNull -> forall a. a -> Maybe a
Just a
a


unnullifier :: Spec a -> Result (Nullify a) -> Maybe (Result a)
unnullifier :: forall a. Spec a -> Result (Nullify a) -> Maybe (Result a)
unnullifier Spec {Nullity a
nullity :: Nullity a
nullity :: forall a. Spec a -> Nullity a
nullity} (Identity Nullify a
a) =
  case Nullity a
nullity of
    Nullity a
Null -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> Identity a
Identity Nullify a
a
    Nullity a
NotNull -> forall a. a -> Identity a
Identity forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Nullify a
a


vectorizer :: Functor f => Spec a -> f (Result a) -> Result (f a)
vectorizer :: forall (f :: * -> *) a.
Functor f =>
Spec a -> f (Result a) -> Result (f a)
vectorizer Spec a
_ = forall a. a -> Identity a
Identity forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Identity a -> a
runIdentity


unvectorizer :: Functor f => Spec a -> Result (f a) -> f (Result a)
unvectorizer :: forall (f :: * -> *) a.
Functor f =>
Spec a -> Result (f a) -> f (Result a)
unvectorizer Spec a
_ (Identity f a
results) = forall a. a -> Identity a
Identity forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
results