module Composite.Opaleye.RecToFields where

import Composite.Record (pattern (:*:), Rec((:&), RNil), (:->)(Val))
import Data.Functor.Identity (Identity(Identity))
import Data.Kind (Type)
import Data.Profunctor.Product.Default (Default)
import Opaleye (ToFields, toFields)

class RecToFields (haskells :: [Type]) (fields :: [Type]) where
  recToFields :: Rec Identity haskells -> Rec Identity fields

instance RecToFields '[] '[] where
  recToFields :: Rec Identity '[] -> Rec Identity '[]
recToFields Rec Identity '[]
RNil = forall {u} (a :: u -> *). Rec a '[]
RNil

instance (Default ToFields h f, RecToFields haskells fields) => RecToFields (s :-> h ': haskells) (s :-> f ': fields) where
  recToFields :: Rec Identity ((s :-> h) : haskells)
-> Rec Identity ((s :-> f) : fields)
recToFields Rec Identity ((s :-> h) : haskells)
hs' = let Identity (Val h
h) :& Rec Identity haskells
Rec Identity rs
hs = Rec Identity ((s :-> h) : haskells)
hs' in forall haskells fields.
Default ToFields haskells fields =>
haskells -> fields
toFields h
h forall a (rs :: [*]) (s :: Symbol).
a -> Rec Identity rs -> Rec Identity ((s :-> a) : rs)
:*: forall (haskells :: [*]) (fields :: [*]).
RecToFields haskells fields =>
Rec Identity haskells -> Rec Identity fields
recToFields Rec Identity haskells
hs