{-# language AllowAmbiguousTypes #-}
{-# language DataKinds #-}
{-# language FlexibleContexts #-}
{-# language FlexibleInstances #-}
{-# language LambdaCase #-}
{-# language MultiParamTypeClasses #-}
{-# language RankNTypes #-}
{-# language ScopedTypeVariables #-}
{-# language StandaloneKindSignatures #-}
{-# language TypeApplications #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
{-# language UndecidableInstances #-}

module Rel8.Generic.Table.ADT
  ( GSerializeADT, GColumnsADT, gfromResultADT, gtoResultADT
  , GSerializeADT', GColumnsADT'
  )
where

-- base
import Data.Functor.Identity ( Identity( Identity ) )
import Data.Kind ( Constraint, Type )
import Data.Proxy ( Proxy( Proxy ) )
import GHC.Generics
  ( (:+:)( L1, R1 ), M1( M1 ), U1( U1 )
  , C, D
  , Meta( MetaCons )
  )
import GHC.TypeLits ( KnownSymbol, symbolVal )
import Prelude hiding ( null )

-- rel8
import Rel8.FCF ( Eval, Exp )
import Rel8.Generic.Table.Record ( GSerialize, GColumns, gfromResult, gtoResult )
import Rel8.Schema.HTable ( HTable )
import Rel8.Schema.HTable.Identity ( HIdentity( HIdentity ) )
import Rel8.Schema.HTable.Label ( HLabel, hlabel, hunlabel )
import Rel8.Schema.HTable.Nullify ( HNullify, hnulls, hnullify, hunnullify )
import Rel8.Schema.HTable.Product ( HProduct( HProduct ) )
import qualified Rel8.Schema.Kind as K
import Rel8.Schema.Result ( Result, null, nullifier, unnullifier )
import Rel8.Type.Tag ( Tag( Tag ) )

-- text
import Data.Text ( pack )


type GColumnsADT
  :: (Type -> Exp K.HTable)
  -> (Type -> Type) -> K.HTable
type family GColumnsADT _Columns rep where
  GColumnsADT _Columns (M1 D _ rep) =
    GColumnsADT' _Columns (HLabel "tag" (HIdentity Tag)) rep


type GColumnsADT'
  :: (Type -> Exp K.HTable)
  -> K.HTable -> (Type -> Type) -> K.HTable
type family GColumnsADT' _Columns htable rep  where
  GColumnsADT' _Columns htable (a :+: b) =
    GColumnsADT' _Columns (GColumnsADT' _Columns htable a) b
  GColumnsADT' _Columns htable (M1 C ('MetaCons _ _ _) U1) = htable
  GColumnsADT' _Columns htable (M1 C ('MetaCons label _ _) rep) =
    HProduct htable (HLabel label (HNullify (GColumns _Columns rep)))


type GSerializeADT
  :: (Type -> Type -> Exp Constraint)
  -> (Type -> Exp K.HTable)
  -> (Type -> Type) -> (Type -> Type) -> Constraint
class GSerializeADT _Serialize _Columns exprs rep where
  gfromResultADT :: ()
    => (forall expr a proxy. Eval (_Serialize expr a)
        => proxy expr -> Eval (_Columns expr) Result -> a)
    -> GColumnsADT _Columns exprs Result
    -> rep x

  gtoResultADT :: ()
    => (forall expr a proxy. Eval (_Serialize expr a)
        => proxy expr -> a -> Eval (_Columns expr) Result)
    -> rep x
    -> GColumnsADT _Columns exprs Result


instance
  ( htable ~ HLabel "tag" (HIdentity Tag)
  , GSerializeADT' _Serialize _Columns htable exprs rep
  )
  => GSerializeADT _Serialize _Columns (M1 D meta exprs) (M1 D meta rep)
 where
  gfromResultADT :: (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) Result -> a)
-> GColumnsADT _Columns (M1 D meta exprs) Result -> M1 D meta rep x
gfromResultADT forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) Result -> a
fromResult GColumnsADT _Columns (M1 D meta exprs) Result
columns =
    case (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) Result -> a)
-> (htable Result -> Tag)
-> GColumnsADT' _Columns htable exprs Result
-> Maybe (rep x)
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) context -> a)
-> (htable Result -> Tag)
-> GColumnsADT' _Columns htable exprs context
-> Maybe (rep x)
gfromResultADT' @_Serialize @_Columns @htable @exprs @rep forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) Result -> a
fromResult htable Result -> Tag
forall c. HLabel "tag" (HIdentity c) Result -> c
tag GColumnsADT' _Columns htable exprs Result
GColumnsADT _Columns (M1 D meta exprs) Result
columns of
      Just rep x
rep -> rep x -> M1 D meta rep x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 rep x
rep
      Maybe (rep x)
_ -> [Char] -> M1 D meta rep x
forall a. HasCallStack => [Char] -> a
error [Char]
"ADT.fromColumns: mismatch between tag and data"
    where
      tag :: HLabel "tag" (HIdentity c) Result -> c
tag = (\(HIdentity (Identity c
a)) -> c
a) (HIdentity c Result -> c)
-> (HLabel "tag" (HIdentity c) Result -> HIdentity c Result)
-> HLabel "tag" (HIdentity c) Result
-> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (label :: Symbol) (t :: HTable) (context :: * -> *).
HLabel label t context -> t context
forall (t :: HTable) (context :: * -> *).
HLabel "tag" t context -> t context
hunlabel @"tag"

  gtoResultADT :: (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> M1 D meta rep x -> GColumnsADT _Columns (M1 D meta exprs) Result
gtoResultADT forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult (M1 rep x
rep) =
    (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> (Tag -> htable Result)
-> Maybe (rep x)
-> GColumnsADT' _Columns htable exprs Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe (rep x)
-> GColumnsADT' _Columns htable exprs context
gtoResultADT' @_Serialize @_Columns @htable @exprs @rep forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult Tag -> htable Result
forall a. a -> HLabel "tag" (HIdentity a) Result
tag (rep x -> Maybe (rep x)
forall a. a -> Maybe a
Just rep x
rep)
    where
      tag :: a -> HLabel "tag" (HIdentity a) Result
tag = forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
forall (t :: HTable) (context :: * -> *).
t context -> HLabel "tag" t context
hlabel @"tag" (HIdentity a Result -> HLabel "tag" (HIdentity a) Result)
-> (a -> HIdentity a Result)
-> a
-> HLabel "tag" (HIdentity a) Result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identity a -> HIdentity a Result
forall a (context :: * -> *). context a -> HIdentity a context
HIdentity (Identity a -> HIdentity a Result)
-> (a -> Identity a) -> a -> HIdentity a Result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Identity a
forall a. a -> Identity a
Identity


type GSerializeADT'
  :: (Type -> Type -> Exp Constraint)
  -> (Type -> Exp K.HTable)
  -> K.HTable -> (Type -> Type) -> (Type -> Type) -> Constraint
class GSerializeADT' _Serialize _Columns htable exprs rep where
  gfromResultADT' :: context ~ Result
    => (forall expr a proxy. Eval (_Serialize expr a)
        => proxy expr -> Eval (_Columns expr) context -> a)
    -> (htable Result -> Tag)
    -> GColumnsADT' _Columns htable exprs context
    -> Maybe (rep x)

  gtoResultADT' :: context ~ Result
    => (forall expr a proxy. Eval (_Serialize expr a)
        => proxy expr -> a -> Eval (_Columns expr) context)
    -> (Tag -> htable Result)
    -> Maybe (rep x)
    -> GColumnsADT' _Columns htable exprs context

  extract :: GColumnsADT' _Columns htable exprs context -> htable context


instance
  ( htable' ~ GColumnsADT' _Columns htable exprs1
  , GSerializeADT' _Serialize _Columns htable exprs1 a
  , GSerializeADT' _Serialize _Columns htable' exprs2 b
  )
  => GSerializeADT' _Serialize _Columns htable (exprs1 :+: exprs2) (a :+: b)
 where
  gfromResultADT' :: (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) context -> a)
-> (htable Result -> Tag)
-> GColumnsADT' _Columns htable (exprs1 :+: exprs2) context
-> Maybe ((:+:) a b x)
gfromResultADT' forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) context -> a
fromResult htable Result -> Tag
f GColumnsADT' _Columns htable (exprs1 :+: exprs2) context
columns =
    case Maybe (a x)
ma of
      Just a x
a -> (:+:) a b x -> Maybe ((:+:) a b x)
forall a. a -> Maybe a
Just (a x -> (:+:) a b x
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 a x
a)
      Maybe (a x)
Nothing -> b x -> (:+:) a b x
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (b x -> (:+:) a b x) -> Maybe (b x) -> Maybe ((:+:) a b x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) Result -> a)
-> (htable' Result -> Tag)
-> GColumnsADT' _Columns htable' exprs2 Result
-> Maybe (b x)
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) context -> a)
-> (htable Result -> Tag)
-> GColumnsADT' _Columns htable exprs context
-> Maybe (rep x)
gfromResultADT' @_Serialize @_Columns @_ @exprs2 @b
          forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) context -> a
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) Result -> a
fromResult
          (htable Result -> Tag
f (htable Result -> Tag)
-> (htable' Result -> htable Result) -> htable' Result -> Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (context :: * -> *).
GSerializeADT' _Serialize _Columns htable exprs1 a =>
GColumnsADT' _Columns htable exprs1 context -> htable context
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *).
GSerializeADT' _Serialize _Columns htable exprs rep =>
GColumnsADT' _Columns htable exprs context -> htable context
extract @_Serialize @_Columns @_ @exprs1 @a)
          GColumnsADT' _Columns htable' exprs2 Result
GColumnsADT' _Columns htable (exprs1 :+: exprs2) context
columns
    where
      ma :: Maybe (a x)
ma =
        (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) Result -> a)
-> (htable Result -> Tag)
-> GColumnsADT' _Columns htable exprs1 Result
-> Maybe (a x)
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) context -> a)
-> (htable Result -> Tag)
-> GColumnsADT' _Columns htable exprs context
-> Maybe (rep x)
gfromResultADT' @_Serialize @_Columns @_ @exprs1 @a
          forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) context -> a
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) Result -> a
fromResult
          htable Result -> Tag
f
          (GColumnsADT' _Columns htable' exprs2 Result -> htable' Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *).
GSerializeADT' _Serialize _Columns htable exprs rep =>
GColumnsADT' _Columns htable exprs context -> htable context
extract @_Serialize @_Columns @_ @exprs2 @b GColumnsADT' _Columns htable' exprs2 Result
GColumnsADT' _Columns htable (exprs1 :+: exprs2) context
columns)

  gtoResultADT' :: (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe ((:+:) a b x)
-> GColumnsADT' _Columns htable (exprs1 :+: exprs2) context
gtoResultADT' forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
toResult Tag -> htable Result
tag = \case
    Just (L1 a x
a) ->
      (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> (Tag -> htable' Result)
-> Maybe (b Any)
-> GColumnsADT' _Columns htable' exprs2 Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe (rep x)
-> GColumnsADT' _Columns htable exprs context
gtoResultADT' @_Serialize @_Columns @_ @exprs2 @b
        forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult
        (\Tag
_ -> (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> (Tag -> htable Result)
-> Maybe (a x)
-> GColumnsADT' _Columns htable exprs1 Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe (rep x)
-> GColumnsADT' _Columns htable exprs context
gtoResultADT' @_Serialize @_Columns @_ @exprs1 @a
          forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult
          Tag -> htable Result
tag
          (a x -> Maybe (a x)
forall a. a -> Maybe a
Just a x
a))
        Maybe (b Any)
forall a. Maybe a
Nothing
    Just (R1 b x
b) ->
      (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> (Tag -> htable' Result)
-> Maybe (b x)
-> GColumnsADT' _Columns htable' exprs2 Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe (rep x)
-> GColumnsADT' _Columns htable exprs context
gtoResultADT' @_Serialize @_Columns @_ @exprs2 @b
        forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult
        (\Tag
tag' ->
          (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> (Tag -> htable Result)
-> Maybe (a Any)
-> GColumnsADT' _Columns htable exprs1 Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe (rep x)
-> GColumnsADT' _Columns htable exprs context
gtoResultADT' @_Serialize @_Columns @_ @exprs1 @a
            forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult
            (\Tag
_ -> Tag -> htable Result
tag Tag
tag')
            Maybe (a Any)
forall a. Maybe a
Nothing)
        (b x -> Maybe (b x)
forall a. a -> Maybe a
Just b x
b)
    Maybe ((:+:) a b x)
Nothing ->
      (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> (Tag -> htable' Result)
-> Maybe (b Any)
-> GColumnsADT' _Columns htable' exprs2 Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe (rep x)
-> GColumnsADT' _Columns htable exprs context
gtoResultADT' @_Serialize @_Columns @_ @exprs2 @b
        forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult
        (\Tag
_ -> (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> (Tag -> htable Result)
-> Maybe (a Any)
-> GColumnsADT' _Columns htable exprs1 Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *) x.
(GSerializeADT' _Serialize _Columns htable exprs rep,
 context ~ Result) =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe (rep x)
-> GColumnsADT' _Columns htable exprs context
gtoResultADT' @_Serialize @_Columns @_ @exprs1 @a forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult Tag -> htable Result
tag Maybe (a Any)
forall a. Maybe a
Nothing)
        Maybe (b Any)
forall a. Maybe a
Nothing

  extract :: GColumnsADT' _Columns htable (exprs1 :+: exprs2) context
-> htable context
extract =
    forall (context :: * -> *).
GSerializeADT' _Serialize _Columns htable exprs1 a =>
GColumnsADT' _Columns htable exprs1 context -> htable context
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *).
GSerializeADT' _Serialize _Columns htable exprs rep =>
GColumnsADT' _Columns htable exprs context -> htable context
extract @_Serialize @_Columns @_ @exprs1 @a (htable' context -> htable context)
-> (GColumnsADT' _Columns htable' exprs2 context
    -> htable' context)
-> GColumnsADT' _Columns htable' exprs2 context
-> htable context
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    forall (context :: * -> *).
GSerializeADT' _Serialize _Columns htable' exprs2 b =>
GColumnsADT' _Columns htable' exprs2 context -> htable' context
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (htable :: HTable) (exprs :: * -> *)
       (rep :: * -> *) (context :: * -> *).
GSerializeADT' _Serialize _Columns htable exprs rep =>
GColumnsADT' _Columns htable exprs context -> htable context
extract @_Serialize @_Columns @_ @exprs2 @b


instance (meta ~ 'MetaCons label _fixity _isRecord, KnownSymbol label) =>
  GSerializeADT' _Serialize _Columns _htable (M1 C meta U1) (M1 C meta U1)
 where
  gfromResultADT' :: (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) context -> a)
-> (_htable Result -> Tag)
-> GColumnsADT' _Columns _htable (M1 C meta U1) context
-> Maybe (M1 C meta U1 x)
gfromResultADT' forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) context -> a
_ _htable Result -> Tag
tag GColumnsADT' _Columns _htable (M1 C meta U1) context
columns
    | _htable Result -> Tag
tag _htable Result
GColumnsADT' _Columns _htable (M1 C meta U1) context
columns Tag -> Tag -> Bool
forall a. Eq a => a -> a -> Bool
== Tag
tag' = M1 C meta U1 x -> Maybe (M1 C meta U1 x)
forall a. a -> Maybe a
Just (U1 x -> M1 C meta U1 x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 U1 x
forall k (p :: k). U1 p
U1)
    | Bool
otherwise = Maybe (M1 C meta U1 x)
forall a. Maybe a
Nothing
    where
      tag' :: Tag
tag' = Text -> Tag
Tag (Text -> Tag) -> Text -> Tag
forall a b. (a -> b) -> a -> b
$ [Char] -> Text
pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Proxy label -> [Char]
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> [Char]
symbolVal (Proxy label
forall k (t :: k). Proxy t
Proxy @label)

  gtoResultADT' :: (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> _htable Result)
-> Maybe (M1 C meta U1 x)
-> GColumnsADT' _Columns _htable (M1 C meta U1) context
gtoResultADT' forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
_ Tag -> _htable Result
tag Maybe (M1 C meta U1 x)
_ = Tag -> _htable Result
tag Tag
tag'
    where
      tag' :: Tag
tag' = Text -> Tag
Tag (Text -> Tag) -> Text -> Tag
forall a b. (a -> b) -> a -> b
$ [Char] -> Text
pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Proxy label -> [Char]
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> [Char]
symbolVal (Proxy label
forall k (t :: k). Proxy t
Proxy @label)

  extract :: GColumnsADT' _Columns _htable (M1 C meta U1) context
-> _htable context
extract = GColumnsADT' _Columns _htable (M1 C meta U1) context
-> _htable context
forall a. a -> a
id


instance {-# OVERLAPPABLE #-}
  ( HTable (GColumns _Columns exprs)
  , GSerialize _Serialize _Columns exprs rep
  , meta ~ 'MetaCons label _fixity _isRecord
  , KnownSymbol label
  , GColumnsADT' _Columns htable (M1 C ('MetaCons label _fixity _isRecord) exprs) ~
      HProduct htable (HLabel label (HNullify (GColumns _Columns exprs)))
  )
  => GSerializeADT' _Serialize _Columns htable (M1 C meta exprs) (M1 C meta rep)
 where
  gfromResultADT' :: (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) context -> a)
-> (htable Result -> Tag)
-> GColumnsADT' _Columns htable (M1 C meta exprs) context
-> Maybe (M1 C meta rep x)
gfromResultADT' forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) context -> a
fromResult htable Result -> Tag
tag (HProduct a b)
    | htable Result -> Tag
tag htable Result
a Tag -> Tag -> Bool
forall a. Eq a => a -> a -> Bool
== Tag
tag' =
        rep x -> M1 C meta rep x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (rep x -> M1 C meta rep x)
-> (GColumns _Columns exprs Result -> rep x)
-> GColumns _Columns exprs Result
-> M1 C meta rep x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) Result -> a)
-> GColumns _Columns exprs Result -> rep x
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (exprs :: * -> *) (rep :: * -> *)
       (context :: * -> *) x.
GSerialize _Serialize _Columns exprs rep =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> Eval (_Columns expr) context -> a)
-> GColumns _Columns exprs context -> rep x
gfromResult @_Serialize @_Columns @exprs @rep forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) context -> a
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> Eval (_Columns expr) Result -> a
fromResult (GColumns _Columns exprs Result -> M1 C meta rep x)
-> Maybe (GColumns _Columns exprs Result)
-> Maybe (M1 C meta rep x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
          (forall a. Spec a -> Result (Nullify a) -> Maybe (Result a))
-> HNullify (GColumns _Columns exprs) Result
-> Maybe (GColumns _Columns exprs Result)
forall (t :: HTable) (m :: * -> *) (context :: * -> *).
(HTable t, Apply m) =>
(forall a. Spec a -> context (Nullify a) -> m (context a))
-> HNullify t context -> m (t context)
hunnullify forall a. Spec a -> Result (Nullify a) -> Maybe (Result a)
unnullifier (HLabel label (HNullify (GColumns _Columns exprs)) Result
-> HNullify (GColumns _Columns exprs) Result
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
HLabel label t context -> t context
hunlabel HLabel label (HNullify (GColumns _Columns exprs)) Result
b)
    | Bool
otherwise = Maybe (M1 C meta rep x)
forall a. Maybe a
Nothing
    where
      tag' :: Tag
tag' = Text -> Tag
Tag (Text -> Tag) -> Text -> Tag
forall a b. (a -> b) -> a -> b
$ [Char] -> Text
pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Proxy label -> [Char]
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> [Char]
symbolVal (Proxy label
forall k (t :: k). Proxy t
Proxy @label)

  gtoResultADT' :: (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> (Tag -> htable Result)
-> Maybe (M1 C meta rep x)
-> GColumnsADT' _Columns htable (M1 C meta exprs) context
gtoResultADT' forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
toResult Tag -> htable Result
tag = \case
    Maybe (M1 C meta rep x)
Nothing -> htable Result
-> HLabel label (HNullify (GColumns _Columns exprs)) Result
-> HProduct
     htable (HLabel label (HNullify (GColumns _Columns exprs))) Result
forall (a :: HTable) (b :: HTable) (context :: * -> *).
a context -> b context -> HProduct a b context
HProduct (Tag -> htable Result
tag Tag
tag') (HNullify (GColumns _Columns exprs) Result
-> HLabel label (HNullify (GColumns _Columns exprs)) Result
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel ((forall a. Spec a -> Result (Nullify a))
-> HNullify (GColumns _Columns exprs) Result
forall (t :: HTable) (context :: * -> *).
HTable t =>
(forall a. Spec a -> context (Nullify a)) -> HNullify t context
hnulls (Result (Maybe (Unnullify' (IsMaybe a) a))
-> Spec a -> Result (Maybe (Unnullify' (IsMaybe a) a))
forall a b. a -> b -> a
const Result (Maybe (Unnullify' (IsMaybe a) a))
forall a. Result (Maybe a)
null)))
    Just (M1 rep x
rep) -> htable Result
-> HLabel label (HNullify (GColumns _Columns exprs)) Result
-> HProduct
     htable (HLabel label (HNullify (GColumns _Columns exprs))) Result
forall (a :: HTable) (b :: HTable) (context :: * -> *).
a context -> b context -> HProduct a b context
HProduct (Tag -> htable Result
tag Tag
tag') (HLabel label (HNullify (GColumns _Columns exprs)) Result
 -> HProduct
      htable (HLabel label (HNullify (GColumns _Columns exprs))) Result)
-> HLabel label (HNullify (GColumns _Columns exprs)) Result
-> HProduct
     htable (HLabel label (HNullify (GColumns _Columns exprs))) Result
forall a b. (a -> b) -> a -> b
$
      HNullify (GColumns _Columns exprs) Result
-> HLabel label (HNullify (GColumns _Columns exprs)) Result
forall (label :: Symbol) (t :: HTable) (context :: * -> *).
t context -> HLabel label t context
hlabel (HNullify (GColumns _Columns exprs) Result
 -> HLabel label (HNullify (GColumns _Columns exprs)) Result)
-> HNullify (GColumns _Columns exprs) Result
-> HLabel label (HNullify (GColumns _Columns exprs)) Result
forall a b. (a -> b) -> a -> b
$
      (forall a. Spec a -> Result a -> Result (Nullify a))
-> GColumns _Columns exprs Result
-> HNullify (GColumns _Columns exprs) Result
forall (t :: HTable) (context :: * -> *).
HTable t =>
(forall a. Spec a -> context a -> context (Nullify a))
-> t context -> HNullify t context
hnullify forall a. Spec a -> Result a -> Result (Nullify a)
nullifier (GColumns _Columns exprs Result
 -> HNullify (GColumns _Columns exprs) Result)
-> GColumns _Columns exprs Result
-> HNullify (GColumns _Columns exprs) Result
forall a b. (a -> b) -> a -> b
$
      (forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) Result)
-> rep x -> GColumns _Columns exprs Result
forall (_Serialize :: * -> * -> Exp Constraint)
       (_Columns :: * -> Exp HTable) (exprs :: * -> *) (rep :: * -> *)
       (context :: * -> *) x.
GSerialize _Serialize _Columns exprs rep =>
(forall expr a (proxy :: * -> *).
 Eval (_Serialize expr a) =>
 proxy expr -> a -> Eval (_Columns expr) context)
-> rep x -> GColumns _Columns exprs context
gtoResult @_Serialize @_Columns @exprs @rep forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) context
forall expr a (proxy :: * -> *).
Eval (_Serialize expr a) =>
proxy expr -> a -> Eval (_Columns expr) Result
toResult rep x
rep
    where
      tag' :: Tag
tag' = Text -> Tag
Tag (Text -> Tag) -> Text -> Tag
forall a b. (a -> b) -> a -> b
$ [Char] -> Text
pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ Proxy label -> [Char]
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> [Char]
symbolVal (Proxy label
forall k (t :: k). Proxy t
Proxy @label)

  extract :: GColumnsADT' _Columns htable (M1 C meta exprs) context
-> htable context
extract (HProduct a _) = htable context
a