{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}

module Cursor.Map.KeyValue
  ( KeyValueCursor (..),
    makeKeyValueCursorKey,
    makeKeyValueCursorValue,
    rebuildKeyValueCursor,
    keyValueCursorSelection,
    mapKeyValueCursor,
    keyValueCursorSelectKey,
    keyValueCursorSelectValue,
    keyValueCursorToggleSelected,
    KeyValueToggle (..),
    traverseKeyValueCursor,
    keyValueCursorTraverseKeyCase,
    keyValueCursorTraverseValueCase,
    foldKeyValueCursor,
  )
where

import Control.DeepSeq
import Data.Validity
import GHC.Generics (Generic)

data KeyValueCursor kc vc k v
  = KeyValueCursorKey kc v
  | KeyValueCursorValue k vc
  deriving (Int -> KeyValueCursor kc vc k v -> ShowS
[KeyValueCursor kc vc k v] -> ShowS
KeyValueCursor kc vc k v -> String
(Int -> KeyValueCursor kc vc k v -> ShowS)
-> (KeyValueCursor kc vc k v -> String)
-> ([KeyValueCursor kc vc k v] -> ShowS)
-> Show (KeyValueCursor kc vc k v)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall kc vc k v.
(Show kc, Show v, Show k, Show vc) =>
Int -> KeyValueCursor kc vc k v -> ShowS
forall kc vc k v.
(Show kc, Show v, Show k, Show vc) =>
[KeyValueCursor kc vc k v] -> ShowS
forall kc vc k v.
(Show kc, Show v, Show k, Show vc) =>
KeyValueCursor kc vc k v -> String
showList :: [KeyValueCursor kc vc k v] -> ShowS
$cshowList :: forall kc vc k v.
(Show kc, Show v, Show k, Show vc) =>
[KeyValueCursor kc vc k v] -> ShowS
show :: KeyValueCursor kc vc k v -> String
$cshow :: forall kc vc k v.
(Show kc, Show v, Show k, Show vc) =>
KeyValueCursor kc vc k v -> String
showsPrec :: Int -> KeyValueCursor kc vc k v -> ShowS
$cshowsPrec :: forall kc vc k v.
(Show kc, Show v, Show k, Show vc) =>
Int -> KeyValueCursor kc vc k v -> ShowS
Show, KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v -> Bool
(KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v -> Bool)
-> (KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v -> Bool)
-> Eq (KeyValueCursor kc vc k v)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall kc vc k v.
(Eq kc, Eq v, Eq k, Eq vc) =>
KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v -> Bool
/= :: KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v -> Bool
$c/= :: forall kc vc k v.
(Eq kc, Eq v, Eq k, Eq vc) =>
KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v -> Bool
== :: KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v -> Bool
$c== :: forall kc vc k v.
(Eq kc, Eq v, Eq k, Eq vc) =>
KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v -> Bool
Eq, (forall x.
 KeyValueCursor kc vc k v -> Rep (KeyValueCursor kc vc k v) x)
-> (forall x.
    Rep (KeyValueCursor kc vc k v) x -> KeyValueCursor kc vc k v)
-> Generic (KeyValueCursor kc vc k v)
forall x.
Rep (KeyValueCursor kc vc k v) x -> KeyValueCursor kc vc k v
forall x.
KeyValueCursor kc vc k v -> Rep (KeyValueCursor kc vc k v) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall kc vc k v x.
Rep (KeyValueCursor kc vc k v) x -> KeyValueCursor kc vc k v
forall kc vc k v x.
KeyValueCursor kc vc k v -> Rep (KeyValueCursor kc vc k v) x
$cto :: forall kc vc k v x.
Rep (KeyValueCursor kc vc k v) x -> KeyValueCursor kc vc k v
$cfrom :: forall kc vc k v x.
KeyValueCursor kc vc k v -> Rep (KeyValueCursor kc vc k v) x
Generic)

instance
  (Validity kc, Validity vc, Validity k, Validity v) =>
  Validity (KeyValueCursor kc vc k v)

instance (NFData kc, NFData vc, NFData k, NFData v) => NFData (KeyValueCursor kc vc k v)

makeKeyValueCursorKey :: kc -> v -> KeyValueCursor kc vc k v
makeKeyValueCursorKey :: kc -> v -> KeyValueCursor kc vc k v
makeKeyValueCursorKey = kc -> v -> KeyValueCursor kc vc k v
forall kc vc k v. kc -> v -> KeyValueCursor kc vc k v
KeyValueCursorKey

makeKeyValueCursorValue :: k -> vc -> KeyValueCursor kc vc k v
makeKeyValueCursorValue :: k -> vc -> KeyValueCursor kc vc k v
makeKeyValueCursorValue = k -> vc -> KeyValueCursor kc vc k v
forall kc vc k v. k -> vc -> KeyValueCursor kc vc k v
KeyValueCursorValue

rebuildKeyValueCursor :: (kc -> k) -> (vc -> v) -> KeyValueCursor kc vc k v -> (k, v)
rebuildKeyValueCursor :: (kc -> k) -> (vc -> v) -> KeyValueCursor kc vc k v -> (k, v)
rebuildKeyValueCursor kc -> k
f vc -> v
_ (KeyValueCursorKey kc
kc v
v) = (kc -> k
f kc
kc, v
v)
rebuildKeyValueCursor kc -> k
_ vc -> v
g (KeyValueCursorValue k
k vc
vc) = (k
k, vc -> v
g vc
vc)

keyValueCursorSelection :: KeyValueCursor kc vc k v -> KeyValueToggle
keyValueCursorSelection :: KeyValueCursor kc vc k v -> KeyValueToggle
keyValueCursorSelection (KeyValueCursorKey kc
_ v
_) = KeyValueToggle
KeySelected
keyValueCursorSelection (KeyValueCursorValue k
_ vc
_) = KeyValueToggle
ValueSelected

mapKeyValueCursor ::
  (kc -> lc) ->
  (vc -> wc) ->
  (k -> l) ->
  (v -> w) ->
  KeyValueCursor kc vc k v ->
  KeyValueCursor lc wc l w
mapKeyValueCursor :: (kc -> lc)
-> (vc -> wc)
-> (k -> l)
-> (v -> w)
-> KeyValueCursor kc vc k v
-> KeyValueCursor lc wc l w
mapKeyValueCursor kc -> lc
a vc -> wc
b k -> l
c v -> w
d KeyValueCursor kc vc k v
kvc =
  case KeyValueCursor kc vc k v
kvc of
    KeyValueCursorKey kc
kc v
v -> lc -> w -> KeyValueCursor lc wc l w
forall kc vc k v. kc -> v -> KeyValueCursor kc vc k v
KeyValueCursorKey (kc -> lc
a kc
kc) (v -> w
d v
v)
    KeyValueCursorValue k
k vc
vc -> l -> wc -> KeyValueCursor lc wc l w
forall kc vc k v. k -> vc -> KeyValueCursor kc vc k v
KeyValueCursorValue (k -> l
c k
k) (vc -> wc
b vc
vc)

keyValueCursorSelectKey ::
  (k -> kc) -> (vc -> v) -> KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v
keyValueCursorSelectKey :: (k -> kc)
-> (vc -> v)
-> KeyValueCursor kc vc k v
-> KeyValueCursor kc vc k v
keyValueCursorSelectKey k -> kc
g vc -> v
h KeyValueCursor kc vc k v
kvc =
  case KeyValueCursor kc vc k v
kvc of
    KeyValueCursorValue k
k vc
vc -> kc -> v -> KeyValueCursor kc vc k v
forall kc vc k v. kc -> v -> KeyValueCursor kc vc k v
KeyValueCursorKey (k -> kc
g k
k) (vc -> v
h vc
vc)
    KeyValueCursor kc vc k v
_ -> KeyValueCursor kc vc k v
kvc

keyValueCursorSelectValue ::
  (kc -> k) -> (v -> vc) -> KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v
keyValueCursorSelectValue :: (kc -> k)
-> (v -> vc)
-> KeyValueCursor kc vc k v
-> KeyValueCursor kc vc k v
keyValueCursorSelectValue kc -> k
f v -> vc
i KeyValueCursor kc vc k v
kvc =
  case KeyValueCursor kc vc k v
kvc of
    KeyValueCursorKey kc
kc v
v -> k -> vc -> KeyValueCursor kc vc k v
forall kc vc k v. k -> vc -> KeyValueCursor kc vc k v
KeyValueCursorValue (kc -> k
f kc
kc) (v -> vc
i v
v)
    KeyValueCursor kc vc k v
_ -> KeyValueCursor kc vc k v
kvc

keyValueCursorToggleSelected ::
  (kc -> k) ->
  (k -> kc) ->
  (vc -> v) ->
  (v -> vc) ->
  KeyValueCursor kc vc k v ->
  KeyValueCursor kc vc k v
keyValueCursorToggleSelected :: (kc -> k)
-> (k -> kc)
-> (vc -> v)
-> (v -> vc)
-> KeyValueCursor kc vc k v
-> KeyValueCursor kc vc k v
keyValueCursorToggleSelected kc -> k
f k -> kc
g vc -> v
h v -> vc
i KeyValueCursor kc vc k v
kvc =
  case KeyValueCursor kc vc k v
kvc of
    KeyValueCursorKey kc
kc v
v -> k -> vc -> KeyValueCursor kc vc k v
forall kc vc k v. k -> vc -> KeyValueCursor kc vc k v
KeyValueCursorValue (kc -> k
f kc
kc) (v -> vc
i v
v)
    KeyValueCursorValue k
k vc
vc -> kc -> v -> KeyValueCursor kc vc k v
forall kc vc k v. kc -> v -> KeyValueCursor kc vc k v
KeyValueCursorKey (k -> kc
g k
k) (vc -> v
h vc
vc)

data KeyValueToggle
  = KeySelected
  | ValueSelected
  deriving (Int -> KeyValueToggle -> ShowS
[KeyValueToggle] -> ShowS
KeyValueToggle -> String
(Int -> KeyValueToggle -> ShowS)
-> (KeyValueToggle -> String)
-> ([KeyValueToggle] -> ShowS)
-> Show KeyValueToggle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KeyValueToggle] -> ShowS
$cshowList :: [KeyValueToggle] -> ShowS
show :: KeyValueToggle -> String
$cshow :: KeyValueToggle -> String
showsPrec :: Int -> KeyValueToggle -> ShowS
$cshowsPrec :: Int -> KeyValueToggle -> ShowS
Show, KeyValueToggle -> KeyValueToggle -> Bool
(KeyValueToggle -> KeyValueToggle -> Bool)
-> (KeyValueToggle -> KeyValueToggle -> Bool) -> Eq KeyValueToggle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KeyValueToggle -> KeyValueToggle -> Bool
$c/= :: KeyValueToggle -> KeyValueToggle -> Bool
== :: KeyValueToggle -> KeyValueToggle -> Bool
$c== :: KeyValueToggle -> KeyValueToggle -> Bool
Eq, (forall x. KeyValueToggle -> Rep KeyValueToggle x)
-> (forall x. Rep KeyValueToggle x -> KeyValueToggle)
-> Generic KeyValueToggle
forall x. Rep KeyValueToggle x -> KeyValueToggle
forall x. KeyValueToggle -> Rep KeyValueToggle x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep KeyValueToggle x -> KeyValueToggle
$cfrom :: forall x. KeyValueToggle -> Rep KeyValueToggle x
Generic)

instance Validity KeyValueToggle

traverseKeyValueCursor :: (kc -> v -> f c) -> (k -> vc -> f c) -> KeyValueCursor kc vc k v -> f c
traverseKeyValueCursor :: (kc -> v -> f c)
-> (k -> vc -> f c) -> KeyValueCursor kc vc k v -> f c
traverseKeyValueCursor = (kc -> v -> f c)
-> (k -> vc -> f c) -> KeyValueCursor kc vc k v -> f c
forall kc v c k vc.
(kc -> v -> c) -> (k -> vc -> c) -> KeyValueCursor kc vc k v -> c
foldKeyValueCursor

keyValueCursorTraverseKeyCase ::
  Applicative f =>
  (kc -> v -> f (kc', v')) ->
  KeyValueCursor kc vc k v ->
  f (KeyValueCursor kc' vc k v')
keyValueCursorTraverseKeyCase :: (kc -> v -> f (kc', v'))
-> KeyValueCursor kc vc k v -> f (KeyValueCursor kc' vc k v')
keyValueCursorTraverseKeyCase kc -> v -> f (kc', v')
func =
  \case
    KeyValueCursorKey kc
kc v
v -> (kc' -> v' -> KeyValueCursor kc' vc k v')
-> (kc', v') -> KeyValueCursor kc' vc k v'
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry kc' -> v' -> KeyValueCursor kc' vc k v'
forall kc vc k v. kc -> v -> KeyValueCursor kc vc k v
KeyValueCursorKey ((kc', v') -> KeyValueCursor kc' vc k v')
-> f (kc', v') -> f (KeyValueCursor kc' vc k v')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> kc -> v -> f (kc', v')
func kc
kc v
v
    KeyValueCursorValue k
k vc
vc -> KeyValueCursor kc' vc k v' -> f (KeyValueCursor kc' vc k v')
forall (f :: * -> *) a. Applicative f => a -> f a
pure (k -> vc -> KeyValueCursor kc' vc k v'
forall kc vc k v. k -> vc -> KeyValueCursor kc vc k v
KeyValueCursorValue k
k vc
vc)

keyValueCursorTraverseValueCase ::
  Applicative f =>
  (k -> vc -> f (k', vc')) ->
  KeyValueCursor kc vc k v ->
  f (KeyValueCursor kc vc' k' v)
keyValueCursorTraverseValueCase :: (k -> vc -> f (k', vc'))
-> KeyValueCursor kc vc k v -> f (KeyValueCursor kc vc' k' v)
keyValueCursorTraverseValueCase k -> vc -> f (k', vc')
func =
  \case
    KeyValueCursorKey kc
kc v
v -> KeyValueCursor kc vc' k' v -> f (KeyValueCursor kc vc' k' v)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (kc -> v -> KeyValueCursor kc vc' k' v
forall kc vc k v. kc -> v -> KeyValueCursor kc vc k v
KeyValueCursorKey kc
kc v
v)
    KeyValueCursorValue k
k vc
vc -> (k' -> vc' -> KeyValueCursor kc vc' k' v)
-> (k', vc') -> KeyValueCursor kc vc' k' v
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry k' -> vc' -> KeyValueCursor kc vc' k' v
forall kc vc k v. k -> vc -> KeyValueCursor kc vc k v
KeyValueCursorValue ((k', vc') -> KeyValueCursor kc vc' k' v)
-> f (k', vc') -> f (KeyValueCursor kc vc' k' v)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> k -> vc -> f (k', vc')
func k
k vc
vc

foldKeyValueCursor :: (kc -> v -> c) -> (k -> vc -> c) -> KeyValueCursor kc vc k v -> c
foldKeyValueCursor :: (kc -> v -> c) -> (k -> vc -> c) -> KeyValueCursor kc vc k v -> c
foldKeyValueCursor kc -> v -> c
keyFunc k -> vc -> c
valFunc KeyValueCursor kc vc k v
kvc =
  case KeyValueCursor kc vc k v
kvc of
    KeyValueCursorKey kc
kc v
v -> kc -> v -> c
keyFunc kc
kc v
v
    KeyValueCursorValue k
k vc
vc -> k -> vc -> c
valFunc k
k vc
vc