{-# 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 :: Result (Maybe a)
null = Maybe a -> Result (Maybe a)
forall a. a -> Identity a
Identity Maybe a
forall a. Maybe a
Nothing


nullifier :: Spec a -> Result a -> Result (Nullify a)
nullifier :: 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) = Nullify a -> Result (Nullify a)
forall a. a -> Identity a
Identity (Nullify a -> Result (Nullify a))
-> Nullify a -> Result (Nullify a)
forall a b. (a -> b) -> a -> b
$ case Nullity a
nullity of
  Nullity a
Null -> a
Nullify a
a
  Nullity a
NotNull -> a -> Maybe a
forall a. a -> Maybe a
Just a
a


unnullifier :: Spec a -> Result (Nullify a) -> Maybe (Result a)
unnullifier :: 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 -> Result a -> Maybe (Result a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Result a -> Maybe (Result a)) -> Result a -> Maybe (Result a)
forall a b. (a -> b) -> a -> b
$ a -> Result a
forall a. a -> Identity a
Identity a
Nullify a
a
    Nullity a
NotNull -> a -> Result a
forall a. a -> Identity a
Identity (a -> Result a) -> Maybe a -> Maybe (Result a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe a
Nullify a
a


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


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