module Sq.Mode
   ( -- * Mode
    Mode (..)
   , SMode (..)
   , fromSMode

    -- * Constraints
   , SubMode
   ) where

import Di.Df1 qualified as Di
import GHC.TypeLits qualified as GHC
import Prelude hiding (Read)

--------------------------------------------------------------------------------

data Mode
   = -- | * A @'Sq.Statement' \''Read'@ performs a read-only query.
     -- Obtain with 'Sq.readStatement'.
     --
     -- * A @'Sq.Transaction' \''Read'@ can permorm \''Read'
     -- 'Sq.Statement's only. Obtain with 'Sq.readTransaction'.
     --
     -- * A @'Sq.Pool' \''Read'@ can permorm \''Read' 'Sq.Transaction's only.
     -- Obtain with 'Sq.readPool' or 'Sq.subPool'.
     Read
   | -- | * A @'Sq.Statement' \''Write'@ performs a read or write query.
     -- Obtain with 'Sq.writeStatement'.
     --
     -- * A @'Sq.Transaction' \''Write'@ can permorm both \''Read' and
     -- \''Write' 'Sq.Statement's. Obtain with 'Sq.commitTransaction' or
     -- 'Sq.rollbackTransaction'.
     --
     -- * A @'Sq.Pool' \''Write'@ can permorm both \''Read' and \''Write'
     -- 'Sq.Transaction's. Obtain with 'Sq.writePool' or 'Sq.tempPool'.
     Write
   deriving stock (Mode -> Mode -> Bool
(Mode -> Mode -> Bool) -> (Mode -> Mode -> Bool) -> Eq Mode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Mode -> Mode -> Bool
== :: Mode -> Mode -> Bool
$c/= :: Mode -> Mode -> Bool
/= :: Mode -> Mode -> Bool
Eq, Eq Mode
Eq Mode =>
(Mode -> Mode -> Ordering)
-> (Mode -> Mode -> Bool)
-> (Mode -> Mode -> Bool)
-> (Mode -> Mode -> Bool)
-> (Mode -> Mode -> Bool)
-> (Mode -> Mode -> Mode)
-> (Mode -> Mode -> Mode)
-> Ord Mode
Mode -> Mode -> Bool
Mode -> Mode -> Ordering
Mode -> Mode -> Mode
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Mode -> Mode -> Ordering
compare :: Mode -> Mode -> Ordering
$c< :: Mode -> Mode -> Bool
< :: Mode -> Mode -> Bool
$c<= :: Mode -> Mode -> Bool
<= :: Mode -> Mode -> Bool
$c> :: Mode -> Mode -> Bool
> :: Mode -> Mode -> Bool
$c>= :: Mode -> Mode -> Bool
>= :: Mode -> Mode -> Bool
$cmax :: Mode -> Mode -> Mode
max :: Mode -> Mode -> Mode
$cmin :: Mode -> Mode -> Mode
min :: Mode -> Mode -> Mode
Ord, Int -> Mode -> ShowS
[Mode] -> ShowS
Mode -> String
(Int -> Mode -> ShowS)
-> (Mode -> String) -> ([Mode] -> ShowS) -> Show Mode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Mode -> ShowS
showsPrec :: Int -> Mode -> ShowS
$cshow :: Mode -> String
show :: Mode -> String
$cshowList :: [Mode] -> ShowS
showList :: [Mode] -> ShowS
Show)

data SMode (mode :: Mode) where
   SRead :: SMode 'Read
   SWrite :: SMode 'Write

fromSMode :: SMode mode -> Mode
fromSMode :: forall (mode :: Mode). SMode mode -> Mode
fromSMode = \case
   SMode mode
SRead -> Mode
Read
   SMode mode
SWrite -> Mode
Write
{-# INLINE fromSMode #-}

instance Di.ToValue Mode where
   value :: Mode -> Value
value = \case
      Mode
Read -> Value
"read"
      Mode
Write -> Value
"write"
   {-# INLINE value #-}

instance Di.ToValue (SMode mode) where
   value :: SMode mode -> Value
value = Mode -> Value
forall a. ToValue a => a -> Value
Di.value (Mode -> Value) -> (SMode mode -> Mode) -> SMode mode -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SMode mode -> Mode
forall (mode :: Mode). SMode mode -> Mode
fromSMode
   {-# INLINE value #-}

--------------------------------------------------------------------------------

class SubMode (sup :: Mode) (sub :: Mode)
instance SubMode Read Read
instance SubMode Write Read
instance SubMode Write Write
instance
   (GHC.TypeError (GHC.Text "Write mode is not a subset of Read mode"))
   => SubMode Read Write