sqel-0.0.1.0: lib/Sqel/Data/Codec.hs
module Sqel.Data.Codec where
import Data.Functor.Invariant (Invariant (invmap), invmapContravariant)
import qualified Hasql.Decoders as Decoders
import Hasql.Decoders (Row)
import qualified Hasql.Encoders as Encoders
import Hasql.Encoders (Params)
import Sqel.SOP.Constraint (symbolText)
data Encoder a =
Encoder {
encodeValue :: Params a,
encodeNulls :: Params ()
}
deriving stock (Generic)
instance Semigroup (Encoder a) where
Encoder vl nl <> Encoder vr nr =
Encoder (vl <> vr) (nl <> nr)
instance Monoid (Encoder a) where
mempty =
Encoder mempty mempty
instance Contravariant Encoder where
contramap f Encoder {..} =
Encoder (f >$< encodeValue) encodeNulls
instance Invariant Encoder where
invmap = invmapContravariant
data Decoder a =
Decoder {
decodeValue :: Row a,
decodeNulls :: Row ()
}
deriving stock (Generic)
instance Functor Decoder where
fmap f Decoder {..} =
Decoder (f <$> decodeValue) decodeNulls
instance Applicative Decoder where
pure a =
Decoder (pure a) (pure ())
liftA2 f (Decoder vl nl) (Decoder vr nr) =
Decoder (liftA2 f vl vr) (nl *> nr)
data Codec e d a =
Codec {
encoder :: e a,
decoder :: d a
}
deriving stock (Generic)
type ValueCodec =
Codec Encoders.Value Decoders.Value
instance (
Contravariant e,
Functor d
) => Invariant (Codec e d) where
invmap f c Codec {..} =
Codec {
encoder = c >$< encoder,
decoder = f <$> decoder
}
type FullCodec =
Codec Encoder Decoder
newtype ColumnName =
ColumnName { unColumnName :: Text }
deriving stock (Eq, Show)
deriving newtype (IsString, Ord)
symbolColumnName ::
∀ (name :: Symbol) .
KnownSymbol name =>
ColumnName
symbolColumnName =
ColumnName (symbolText @name)