{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Rel8.Internal.Expr.Range (
  range,  
  multirange,
) where

-- rel8
import Rel8.Internal.Data.Range (
  Range, mapRange, quoteRange,
  Multirange, primMultirange,
 )
import Rel8.Internal.Expr (Expr)
import Rel8.Internal.Expr.Opaleye (fromPrimExpr, toPrimExpr)
import Rel8.Internal.Type.Range (DBRange, rangeTypeName, multirangeTypeName)


range :: forall a. DBRange a => Range (Expr a) -> Expr (Range a)
range :: forall a. DBRange a => Range (Expr a) -> Expr (Range a)
range = PrimExpr -> Expr (Range a)
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr (Range a))
-> (Range (Expr a) -> PrimExpr) -> Range (Expr a) -> Expr (Range a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualifiedName -> Range PrimExpr -> PrimExpr
quoteRange QualifiedName
name (Range PrimExpr -> PrimExpr)
-> (Range (Expr a) -> Range PrimExpr) -> Range (Expr a) -> PrimExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr a -> PrimExpr) -> Range (Expr a) -> Range PrimExpr
forall a b. (a -> b) -> Range a -> Range b
mapRange Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr
  where
    name :: QualifiedName
name = forall a. DBRange a => QualifiedName
rangeTypeName @a


multirange :: forall a. DBRange a => [Expr (Range a)] -> Expr (Multirange a)
multirange :: forall a. DBRange a => [Expr (Range a)] -> Expr (Multirange a)
multirange = PrimExpr -> Expr (Multirange a)
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr (Multirange a))
-> ([Expr (Range a)] -> PrimExpr)
-> [Expr (Range a)]
-> Expr (Multirange a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualifiedName -> [PrimExpr] -> PrimExpr
primMultirange QualifiedName
name ([PrimExpr] -> PrimExpr)
-> ([Expr (Range a)] -> [PrimExpr]) -> [Expr (Range a)] -> PrimExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr (Range a) -> PrimExpr) -> [Expr (Range a)] -> [PrimExpr]
forall a b. (a -> b) -> [a] -> [b]
map Expr (Range a) -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr
  where
    name :: QualifiedName
name = forall a. DBRange a => QualifiedName
multirangeTypeName @a