{-# LANGUAGE DeriveAnyClass #-}

-- | A name for a logical model as it is recognized by the graphql schema.
module Hasura.LogicalModel.Types
  ( LogicalModelName (..),
    LogicalModelField (..),
    LogicalModelType (..),
    LogicalModelTypeScalar (..),
    LogicalModelTypeArray (..),
    LogicalModelTypeReference (..),
    logicalModelFieldMapCodec,
  )
where

import Autodocodec
  ( HasCodec (codec),
    dimapCodec,
  )
import Autodocodec qualified as AC
import Data.Aeson (FromJSON (..), FromJSONKey, ToJSON (..), ToJSONKey, Value)
import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap
import Data.Text.Extended (ToTxt)
import Hasura.Metadata.DTO.Placeholder (placeholderCodecViaJSON)
import Hasura.Prelude hiding (first)
import Hasura.RQL.Types.Backend (Backend (..))
import Hasura.RQL.Types.BackendTag (backendPrefix)
import Language.GraphQL.Draft.Syntax qualified as G
import Language.Haskell.TH.Syntax (Lift)

-- The name of a logical model. This appears as a root field name in the graphql schema.
newtype LogicalModelName = LogicalModelName {LogicalModelName -> Name
getLogicalModelName :: G.Name}
  deriving newtype (LogicalModelName -> LogicalModelName -> Bool
(LogicalModelName -> LogicalModelName -> Bool)
-> (LogicalModelName -> LogicalModelName -> Bool)
-> Eq LogicalModelName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LogicalModelName -> LogicalModelName -> Bool
== :: LogicalModelName -> LogicalModelName -> Bool
$c/= :: LogicalModelName -> LogicalModelName -> Bool
/= :: LogicalModelName -> LogicalModelName -> Bool
Eq, Eq LogicalModelName
Eq LogicalModelName
-> (LogicalModelName -> LogicalModelName -> Ordering)
-> (LogicalModelName -> LogicalModelName -> Bool)
-> (LogicalModelName -> LogicalModelName -> Bool)
-> (LogicalModelName -> LogicalModelName -> Bool)
-> (LogicalModelName -> LogicalModelName -> Bool)
-> (LogicalModelName -> LogicalModelName -> LogicalModelName)
-> (LogicalModelName -> LogicalModelName -> LogicalModelName)
-> Ord LogicalModelName
LogicalModelName -> LogicalModelName -> Bool
LogicalModelName -> LogicalModelName -> Ordering
LogicalModelName -> LogicalModelName -> LogicalModelName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: LogicalModelName -> LogicalModelName -> Ordering
compare :: LogicalModelName -> LogicalModelName -> Ordering
$c< :: LogicalModelName -> LogicalModelName -> Bool
< :: LogicalModelName -> LogicalModelName -> Bool
$c<= :: LogicalModelName -> LogicalModelName -> Bool
<= :: LogicalModelName -> LogicalModelName -> Bool
$c> :: LogicalModelName -> LogicalModelName -> Bool
> :: LogicalModelName -> LogicalModelName -> Bool
$c>= :: LogicalModelName -> LogicalModelName -> Bool
>= :: LogicalModelName -> LogicalModelName -> Bool
$cmax :: LogicalModelName -> LogicalModelName -> LogicalModelName
max :: LogicalModelName -> LogicalModelName -> LogicalModelName
$cmin :: LogicalModelName -> LogicalModelName -> LogicalModelName
min :: LogicalModelName -> LogicalModelName -> LogicalModelName
Ord, Int -> LogicalModelName -> ShowS
[LogicalModelName] -> ShowS
LogicalModelName -> String
(Int -> LogicalModelName -> ShowS)
-> (LogicalModelName -> String)
-> ([LogicalModelName] -> ShowS)
-> Show LogicalModelName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LogicalModelName -> ShowS
showsPrec :: Int -> LogicalModelName -> ShowS
$cshow :: LogicalModelName -> String
show :: LogicalModelName -> String
$cshowList :: [LogicalModelName] -> ShowS
showList :: [LogicalModelName] -> ShowS
Show, Eq LogicalModelName
Eq LogicalModelName
-> (Int -> LogicalModelName -> Int)
-> (LogicalModelName -> Int)
-> Hashable LogicalModelName
Int -> LogicalModelName -> Int
LogicalModelName -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> LogicalModelName -> Int
hashWithSalt :: Int -> LogicalModelName -> Int
$chash :: LogicalModelName -> Int
hash :: LogicalModelName -> Int
Hashable, LogicalModelName -> ()
(LogicalModelName -> ()) -> NFData LogicalModelName
forall a. (a -> ()) -> NFData a
$crnf :: LogicalModelName -> ()
rnf :: LogicalModelName -> ()
NFData, [LogicalModelName] -> Value
[LogicalModelName] -> Encoding
LogicalModelName -> Value
LogicalModelName -> Encoding
(LogicalModelName -> Value)
-> (LogicalModelName -> Encoding)
-> ([LogicalModelName] -> Value)
-> ([LogicalModelName] -> Encoding)
-> ToJSON LogicalModelName
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: LogicalModelName -> Value
toJSON :: LogicalModelName -> Value
$ctoEncoding :: LogicalModelName -> Encoding
toEncoding :: LogicalModelName -> Encoding
$ctoJSONList :: [LogicalModelName] -> Value
toJSONList :: [LogicalModelName] -> Value
$ctoEncodingList :: [LogicalModelName] -> Encoding
toEncodingList :: [LogicalModelName] -> Encoding
ToJSON, Value -> Parser [LogicalModelName]
Value -> Parser LogicalModelName
(Value -> Parser LogicalModelName)
-> (Value -> Parser [LogicalModelName])
-> FromJSON LogicalModelName
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser LogicalModelName
parseJSON :: Value -> Parser LogicalModelName
$cparseJSONList :: Value -> Parser [LogicalModelName]
parseJSONList :: Value -> Parser [LogicalModelName]
FromJSON, LogicalModelName -> Text
(LogicalModelName -> Text) -> ToTxt LogicalModelName
forall a. (a -> Text) -> ToTxt a
$ctoTxt :: LogicalModelName -> Text
toTxt :: LogicalModelName -> Text
ToTxt)
  deriving stock (Typeable LogicalModelName
Typeable LogicalModelName
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LogicalModelName -> c LogicalModelName)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LogicalModelName)
-> (LogicalModelName -> Constr)
-> (LogicalModelName -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LogicalModelName))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c LogicalModelName))
-> ((forall b. Data b => b -> b)
    -> LogicalModelName -> LogicalModelName)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LogicalModelName -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LogicalModelName -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> LogicalModelName -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> LogicalModelName -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> LogicalModelName -> m LogicalModelName)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> LogicalModelName -> m LogicalModelName)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> LogicalModelName -> m LogicalModelName)
-> Data LogicalModelName
LogicalModelName -> Constr
LogicalModelName -> DataType
(forall b. Data b => b -> b)
-> LogicalModelName -> LogicalModelName
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> LogicalModelName -> u
forall u. (forall d. Data d => d -> u) -> LogicalModelName -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LogicalModelName -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LogicalModelName -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> LogicalModelName -> m LogicalModelName
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LogicalModelName -> m LogicalModelName
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LogicalModelName
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LogicalModelName -> c LogicalModelName
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LogicalModelName)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LogicalModelName)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LogicalModelName -> c LogicalModelName
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LogicalModelName -> c LogicalModelName
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LogicalModelName
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LogicalModelName
$ctoConstr :: LogicalModelName -> Constr
toConstr :: LogicalModelName -> Constr
$cdataTypeOf :: LogicalModelName -> DataType
dataTypeOf :: LogicalModelName -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LogicalModelName)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LogicalModelName)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LogicalModelName)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LogicalModelName)
$cgmapT :: (forall b. Data b => b -> b)
-> LogicalModelName -> LogicalModelName
gmapT :: (forall b. Data b => b -> b)
-> LogicalModelName -> LogicalModelName
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LogicalModelName -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LogicalModelName -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LogicalModelName -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LogicalModelName -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> LogicalModelName -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> LogicalModelName -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> LogicalModelName -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> LogicalModelName -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> LogicalModelName -> m LogicalModelName
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> LogicalModelName -> m LogicalModelName
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LogicalModelName -> m LogicalModelName
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LogicalModelName -> m LogicalModelName
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LogicalModelName -> m LogicalModelName
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LogicalModelName -> m LogicalModelName
Data, (forall x. LogicalModelName -> Rep LogicalModelName x)
-> (forall x. Rep LogicalModelName x -> LogicalModelName)
-> Generic LogicalModelName
forall x. Rep LogicalModelName x -> LogicalModelName
forall x. LogicalModelName -> Rep LogicalModelName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LogicalModelName -> Rep LogicalModelName x
from :: forall x. LogicalModelName -> Rep LogicalModelName x
$cto :: forall x. Rep LogicalModelName x -> LogicalModelName
to :: forall x. Rep LogicalModelName x -> LogicalModelName
Generic, (forall (m :: * -> *). Quote m => LogicalModelName -> m Exp)
-> (forall (m :: * -> *).
    Quote m =>
    LogicalModelName -> Code m LogicalModelName)
-> Lift LogicalModelName
forall t.
(forall (m :: * -> *). Quote m => t -> m Exp)
-> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
forall (m :: * -> *). Quote m => LogicalModelName -> m Exp
forall (m :: * -> *).
Quote m =>
LogicalModelName -> Code m LogicalModelName
$clift :: forall (m :: * -> *). Quote m => LogicalModelName -> m Exp
lift :: forall (m :: * -> *). Quote m => LogicalModelName -> m Exp
$cliftTyped :: forall (m :: * -> *).
Quote m =>
LogicalModelName -> Code m LogicalModelName
liftTyped :: forall (m :: * -> *).
Quote m =>
LogicalModelName -> Code m LogicalModelName
Lift)

instance HasCodec LogicalModelName where
  codec :: JSONCodec LogicalModelName
codec = (Name -> LogicalModelName)
-> (LogicalModelName -> Name)
-> Codec Value Name Name
-> JSONCodec LogicalModelName
forall oldOutput newOutput newInput oldInput context.
(oldOutput -> newOutput)
-> (newInput -> oldInput)
-> Codec context oldInput oldOutput
-> Codec context newInput newOutput
dimapCodec Name -> LogicalModelName
LogicalModelName LogicalModelName -> Name
getLogicalModelName Codec Value Name Name
forall value. HasCodec value => JSONCodec value
codec

instance FromJSONKey LogicalModelName

instance ToJSONKey LogicalModelName

----

data LogicalModelTypeScalar b = LogicalModelTypeScalarC
  { forall (b :: BackendType). LogicalModelTypeScalar b -> ScalarType b
lmtsScalar :: ScalarType b,
    forall (b :: BackendType). LogicalModelTypeScalar b -> Bool
lmtsNullable :: Bool
  }
  deriving ((forall x.
 LogicalModelTypeScalar b -> Rep (LogicalModelTypeScalar b) x)
-> (forall x.
    Rep (LogicalModelTypeScalar b) x -> LogicalModelTypeScalar b)
-> Generic (LogicalModelTypeScalar b)
forall x.
Rep (LogicalModelTypeScalar b) x -> LogicalModelTypeScalar b
forall x.
LogicalModelTypeScalar b -> Rep (LogicalModelTypeScalar b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) x.
Rep (LogicalModelTypeScalar b) x -> LogicalModelTypeScalar b
forall (b :: BackendType) x.
LogicalModelTypeScalar b -> Rep (LogicalModelTypeScalar b) x
$cfrom :: forall (b :: BackendType) x.
LogicalModelTypeScalar b -> Rep (LogicalModelTypeScalar b) x
from :: forall x.
LogicalModelTypeScalar b -> Rep (LogicalModelTypeScalar b) x
$cto :: forall (b :: BackendType) x.
Rep (LogicalModelTypeScalar b) x -> LogicalModelTypeScalar b
to :: forall x.
Rep (LogicalModelTypeScalar b) x -> LogicalModelTypeScalar b
Generic)

deriving stock instance (Backend b) => Eq (LogicalModelTypeScalar b)

deriving stock instance (Backend b) => Show (LogicalModelTypeScalar b)

instance (Backend b) => Hashable (LogicalModelTypeScalar b)

instance (Backend b) => NFData (LogicalModelTypeScalar b)

instance (Backend b) => HasCodec (LogicalModelTypeScalar b) where
  codec :: JSONCodec (LogicalModelTypeScalar b)
codec =
    Text
-> JSONCodec (LogicalModelTypeScalar b)
-> JSONCodec (LogicalModelTypeScalar b)
forall input output.
Text -> ValueCodec input output -> ValueCodec input output
AC.CommentCodec
      (Text
"A scalar type used in a Logical Model.")
      (JSONCodec (LogicalModelTypeScalar b)
 -> JSONCodec (LogicalModelTypeScalar b))
-> JSONCodec (LogicalModelTypeScalar b)
-> JSONCodec (LogicalModelTypeScalar b)
forall a b. (a -> b) -> a -> b
$ Text
-> ObjectCodec
     (LogicalModelTypeScalar b) (LogicalModelTypeScalar b)
-> JSONCodec (LogicalModelTypeScalar b)
forall input output.
Text -> ObjectCodec input output -> ValueCodec input output
AC.object (forall (b :: BackendType). HasTag b => Text
backendPrefix @b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"LogicalModelTypeScalar")
      (ObjectCodec (LogicalModelTypeScalar b) (LogicalModelTypeScalar b)
 -> JSONCodec (LogicalModelTypeScalar b))
-> ObjectCodec
     (LogicalModelTypeScalar b) (LogicalModelTypeScalar b)
-> JSONCodec (LogicalModelTypeScalar b)
forall a b. (a -> b) -> a -> b
$ ScalarType b -> Bool -> LogicalModelTypeScalar b
forall (b :: BackendType).
ScalarType b -> Bool -> LogicalModelTypeScalar b
LogicalModelTypeScalarC
      (ScalarType b -> Bool -> LogicalModelTypeScalar b)
-> Codec Object (LogicalModelTypeScalar b) (ScalarType b)
-> Codec
     Object
     (LogicalModelTypeScalar b)
     (Bool -> LogicalModelTypeScalar b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Text -> ObjectCodec (ScalarType b) (ScalarType b)
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec output output
AC.requiredField Text
"scalar" Text
scalarDoc
      ObjectCodec (ScalarType b) (ScalarType b)
-> (LogicalModelTypeScalar b -> ScalarType b)
-> Codec Object (LogicalModelTypeScalar b) (ScalarType b)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelTypeScalar b -> ScalarType b
forall (b :: BackendType). LogicalModelTypeScalar b -> ScalarType b
lmtsScalar
        Codec
  Object
  (LogicalModelTypeScalar b)
  (Bool -> LogicalModelTypeScalar b)
-> Codec Object (LogicalModelTypeScalar b) Bool
-> ObjectCodec
     (LogicalModelTypeScalar b) (LogicalModelTypeScalar b)
forall a b.
Codec Object (LogicalModelTypeScalar b) (a -> b)
-> Codec Object (LogicalModelTypeScalar b) a
-> Codec Object (LogicalModelTypeScalar b) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Bool -> Text -> ObjectCodec Bool Bool
forall output.
HasCodec output =>
Text -> output -> Text -> ObjectCodec output output
AC.optionalFieldWithDefault Text
"nullable" Bool
False Text
nullableDoc
      ObjectCodec Bool Bool
-> (LogicalModelTypeScalar b -> Bool)
-> Codec Object (LogicalModelTypeScalar b) Bool
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelTypeScalar b -> Bool
forall (b :: BackendType). LogicalModelTypeScalar b -> Bool
lmtsNullable
    where
      scalarDoc :: Text
scalarDoc = Text
"Name of the scalar type"
      nullableDoc :: Text
nullableDoc = Text
"Whether this field is allowed to contain null values or not"

deriving via
  (AC.Autodocodec (LogicalModelTypeScalar b))
  instance
    (Backend b) => (FromJSON (LogicalModelTypeScalar b))

deriving via
  (AC.Autodocodec (LogicalModelTypeScalar b))
  instance
    (Backend b) => (ToJSON (LogicalModelTypeScalar b))

----

data LogicalModelTypeArray b = LogicalModelTypeArrayC
  { forall (b :: BackendType).
LogicalModelTypeArray b -> LogicalModelType b
lmtaArray :: LogicalModelType b,
    forall (b :: BackendType). LogicalModelTypeArray b -> Bool
lmtaNullable :: Bool
  }
  deriving ((forall x.
 LogicalModelTypeArray b -> Rep (LogicalModelTypeArray b) x)
-> (forall x.
    Rep (LogicalModelTypeArray b) x -> LogicalModelTypeArray b)
-> Generic (LogicalModelTypeArray b)
forall x.
Rep (LogicalModelTypeArray b) x -> LogicalModelTypeArray b
forall x.
LogicalModelTypeArray b -> Rep (LogicalModelTypeArray b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) x.
Rep (LogicalModelTypeArray b) x -> LogicalModelTypeArray b
forall (b :: BackendType) x.
LogicalModelTypeArray b -> Rep (LogicalModelTypeArray b) x
$cfrom :: forall (b :: BackendType) x.
LogicalModelTypeArray b -> Rep (LogicalModelTypeArray b) x
from :: forall x.
LogicalModelTypeArray b -> Rep (LogicalModelTypeArray b) x
$cto :: forall (b :: BackendType) x.
Rep (LogicalModelTypeArray b) x -> LogicalModelTypeArray b
to :: forall x.
Rep (LogicalModelTypeArray b) x -> LogicalModelTypeArray b
Generic)

deriving stock instance (Backend b) => Eq (LogicalModelTypeArray b)

deriving stock instance (Backend b) => Show (LogicalModelTypeArray b)

instance (Backend b) => Hashable (LogicalModelTypeArray b)

instance (Backend b) => NFData (LogicalModelTypeArray b)

instance (Backend b) => HasCodec (LogicalModelTypeArray b) where
  codec :: JSONCodec (LogicalModelTypeArray b)
codec =
    Text
-> JSONCodec (LogicalModelTypeArray b)
-> JSONCodec (LogicalModelTypeArray b)
forall input output.
Text -> ValueCodec input output -> ValueCodec input output
AC.CommentCodec
      (Text
"An array type used in a Logical Model.")
      (JSONCodec (LogicalModelTypeArray b)
 -> JSONCodec (LogicalModelTypeArray b))
-> JSONCodec (LogicalModelTypeArray b)
-> JSONCodec (LogicalModelTypeArray b)
forall a b. (a -> b) -> a -> b
$ Text
-> ObjectCodec (LogicalModelTypeArray b) (LogicalModelTypeArray b)
-> JSONCodec (LogicalModelTypeArray b)
forall input output.
Text -> ObjectCodec input output -> ValueCodec input output
AC.object (forall (b :: BackendType). HasTag b => Text
backendPrefix @b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"LogicalModelTypeArray")
      (ObjectCodec (LogicalModelTypeArray b) (LogicalModelTypeArray b)
 -> JSONCodec (LogicalModelTypeArray b))
-> ObjectCodec (LogicalModelTypeArray b) (LogicalModelTypeArray b)
-> JSONCodec (LogicalModelTypeArray b)
forall a b. (a -> b) -> a -> b
$ LogicalModelType b -> Bool -> LogicalModelTypeArray b
forall (b :: BackendType).
LogicalModelType b -> Bool -> LogicalModelTypeArray b
LogicalModelTypeArrayC
      (LogicalModelType b -> Bool -> LogicalModelTypeArray b)
-> Codec Object (LogicalModelTypeArray b) (LogicalModelType b)
-> Codec
     Object (LogicalModelTypeArray b) (Bool -> LogicalModelTypeArray b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> Text -> ObjectCodec (LogicalModelType b) (LogicalModelType b)
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec output output
AC.requiredField Text
"array" Text
arrayDoc
      ObjectCodec (LogicalModelType b) (LogicalModelType b)
-> (LogicalModelTypeArray b -> LogicalModelType b)
-> Codec Object (LogicalModelTypeArray b) (LogicalModelType b)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelTypeArray b -> LogicalModelType b
forall (b :: BackendType).
LogicalModelTypeArray b -> LogicalModelType b
lmtaArray
        Codec
  Object (LogicalModelTypeArray b) (Bool -> LogicalModelTypeArray b)
-> Codec Object (LogicalModelTypeArray b) Bool
-> ObjectCodec (LogicalModelTypeArray b) (LogicalModelTypeArray b)
forall a b.
Codec Object (LogicalModelTypeArray b) (a -> b)
-> Codec Object (LogicalModelTypeArray b) a
-> Codec Object (LogicalModelTypeArray b) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Bool -> Text -> ObjectCodec Bool Bool
forall output.
HasCodec output =>
Text -> output -> Text -> ObjectCodec output output
AC.optionalFieldWithDefault Text
"nullable" Bool
False Text
nullableDoc
      ObjectCodec Bool Bool
-> (LogicalModelTypeArray b -> Bool)
-> Codec Object (LogicalModelTypeArray b) Bool
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelTypeArray b -> Bool
forall (b :: BackendType). LogicalModelTypeArray b -> Bool
lmtaNullable
    where
      arrayDoc :: Text
arrayDoc = Text
"Type of items inside array"
      nullableDoc :: Text
nullableDoc = Text
"Whether this field can be null or not"

deriving via
  (AC.Autodocodec (LogicalModelTypeArray b))
  instance
    (Backend b) => (FromJSON (LogicalModelTypeArray b))

deriving via
  (AC.Autodocodec (LogicalModelTypeArray b))
  instance
    (Backend b) => (ToJSON (LogicalModelTypeArray b))

----

data LogicalModelTypeReference = LogicalModelTypeReferenceC
  { LogicalModelTypeReference -> LogicalModelName
lmtrReference :: LogicalModelName,
    LogicalModelTypeReference -> Bool
lmtrNullable :: Bool
  }
  deriving stock (LogicalModelTypeReference -> LogicalModelTypeReference -> Bool
(LogicalModelTypeReference -> LogicalModelTypeReference -> Bool)
-> (LogicalModelTypeReference -> LogicalModelTypeReference -> Bool)
-> Eq LogicalModelTypeReference
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LogicalModelTypeReference -> LogicalModelTypeReference -> Bool
== :: LogicalModelTypeReference -> LogicalModelTypeReference -> Bool
$c/= :: LogicalModelTypeReference -> LogicalModelTypeReference -> Bool
/= :: LogicalModelTypeReference -> LogicalModelTypeReference -> Bool
Eq, Int -> LogicalModelTypeReference -> ShowS
[LogicalModelTypeReference] -> ShowS
LogicalModelTypeReference -> String
(Int -> LogicalModelTypeReference -> ShowS)
-> (LogicalModelTypeReference -> String)
-> ([LogicalModelTypeReference] -> ShowS)
-> Show LogicalModelTypeReference
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LogicalModelTypeReference -> ShowS
showsPrec :: Int -> LogicalModelTypeReference -> ShowS
$cshow :: LogicalModelTypeReference -> String
show :: LogicalModelTypeReference -> String
$cshowList :: [LogicalModelTypeReference] -> ShowS
showList :: [LogicalModelTypeReference] -> ShowS
Show, (forall x.
 LogicalModelTypeReference -> Rep LogicalModelTypeReference x)
-> (forall x.
    Rep LogicalModelTypeReference x -> LogicalModelTypeReference)
-> Generic LogicalModelTypeReference
forall x.
Rep LogicalModelTypeReference x -> LogicalModelTypeReference
forall x.
LogicalModelTypeReference -> Rep LogicalModelTypeReference x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x.
LogicalModelTypeReference -> Rep LogicalModelTypeReference x
from :: forall x.
LogicalModelTypeReference -> Rep LogicalModelTypeReference x
$cto :: forall x.
Rep LogicalModelTypeReference x -> LogicalModelTypeReference
to :: forall x.
Rep LogicalModelTypeReference x -> LogicalModelTypeReference
Generic)
  deriving anyclass (Eq LogicalModelTypeReference
Eq LogicalModelTypeReference
-> (Int -> LogicalModelTypeReference -> Int)
-> (LogicalModelTypeReference -> Int)
-> Hashable LogicalModelTypeReference
Int -> LogicalModelTypeReference -> Int
LogicalModelTypeReference -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> LogicalModelTypeReference -> Int
hashWithSalt :: Int -> LogicalModelTypeReference -> Int
$chash :: LogicalModelTypeReference -> Int
hash :: LogicalModelTypeReference -> Int
Hashable, LogicalModelTypeReference -> ()
(LogicalModelTypeReference -> ())
-> NFData LogicalModelTypeReference
forall a. (a -> ()) -> NFData a
$crnf :: LogicalModelTypeReference -> ()
rnf :: LogicalModelTypeReference -> ()
NFData)

instance HasCodec LogicalModelTypeReference where
  codec :: JSONCodec LogicalModelTypeReference
codec =
    Text
-> JSONCodec LogicalModelTypeReference
-> JSONCodec LogicalModelTypeReference
forall input output.
Text -> ValueCodec input output -> ValueCodec input output
AC.CommentCodec
      (Text
"A reference to another Logical Model.")
      (JSONCodec LogicalModelTypeReference
 -> JSONCodec LogicalModelTypeReference)
-> JSONCodec LogicalModelTypeReference
-> JSONCodec LogicalModelTypeReference
forall a b. (a -> b) -> a -> b
$ Text
-> ObjectCodec LogicalModelTypeReference LogicalModelTypeReference
-> JSONCodec LogicalModelTypeReference
forall input output.
Text -> ObjectCodec input output -> ValueCodec input output
AC.object Text
"LogicalModelTypeReference"
      (ObjectCodec LogicalModelTypeReference LogicalModelTypeReference
 -> JSONCodec LogicalModelTypeReference)
-> ObjectCodec LogicalModelTypeReference LogicalModelTypeReference
-> JSONCodec LogicalModelTypeReference
forall a b. (a -> b) -> a -> b
$ LogicalModelName -> Bool -> LogicalModelTypeReference
LogicalModelTypeReferenceC
      (LogicalModelName -> Bool -> LogicalModelTypeReference)
-> Codec Object LogicalModelTypeReference LogicalModelName
-> Codec
     Object
     LogicalModelTypeReference
     (Bool -> LogicalModelTypeReference)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Text -> ObjectCodec LogicalModelName LogicalModelName
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec output output
AC.requiredField Text
"logical_model" Text
referenceDoc
      ObjectCodec LogicalModelName LogicalModelName
-> (LogicalModelTypeReference -> LogicalModelName)
-> Codec Object LogicalModelTypeReference LogicalModelName
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelTypeReference -> LogicalModelName
lmtrReference
        Codec
  Object
  LogicalModelTypeReference
  (Bool -> LogicalModelTypeReference)
-> Codec Object LogicalModelTypeReference Bool
-> ObjectCodec LogicalModelTypeReference LogicalModelTypeReference
forall a b.
Codec Object LogicalModelTypeReference (a -> b)
-> Codec Object LogicalModelTypeReference a
-> Codec Object LogicalModelTypeReference b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Bool -> Text -> ObjectCodec Bool Bool
forall output.
HasCodec output =>
Text -> output -> Text -> ObjectCodec output output
AC.optionalFieldWithDefault Text
"nullable" Bool
False Text
nullableDoc
      ObjectCodec Bool Bool
-> (LogicalModelTypeReference -> Bool)
-> Codec Object LogicalModelTypeReference Bool
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelTypeReference -> Bool
lmtrNullable
    where
      referenceDoc :: Text
referenceDoc = Text
"Name of another Logical Model to nest"
      nullableDoc :: Text
nullableDoc = Text
"Whether this field can be null or not"

deriving via
  (AC.Autodocodec LogicalModelTypeReference)
  instance
    (FromJSON LogicalModelTypeReference)

deriving via
  (AC.Autodocodec LogicalModelTypeReference)
  instance
    (ToJSON LogicalModelTypeReference)

----

data LogicalModelType b
  = LogicalModelTypeScalar (LogicalModelTypeScalar b)
  | LogicalModelTypeArray (LogicalModelTypeArray b)
  | LogicalModelTypeReference LogicalModelTypeReference
  deriving ((forall x. LogicalModelType b -> Rep (LogicalModelType b) x)
-> (forall x. Rep (LogicalModelType b) x -> LogicalModelType b)
-> Generic (LogicalModelType b)
forall x. Rep (LogicalModelType b) x -> LogicalModelType b
forall x. LogicalModelType b -> Rep (LogicalModelType b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) x.
Rep (LogicalModelType b) x -> LogicalModelType b
forall (b :: BackendType) x.
LogicalModelType b -> Rep (LogicalModelType b) x
$cfrom :: forall (b :: BackendType) x.
LogicalModelType b -> Rep (LogicalModelType b) x
from :: forall x. LogicalModelType b -> Rep (LogicalModelType b) x
$cto :: forall (b :: BackendType) x.
Rep (LogicalModelType b) x -> LogicalModelType b
to :: forall x. Rep (LogicalModelType b) x -> LogicalModelType b
Generic)

deriving stock instance (Backend b) => Eq (LogicalModelType b)

deriving stock instance (Backend b) => Show (LogicalModelType b)

instance (Backend b) => Hashable (LogicalModelType b)

instance (Backend b) => NFData (LogicalModelType b)

-- | forgive me, I really did try and do this the native Autodocodec way
-- and everything I did kept freezing the whole of HGE
instance (Backend b) => HasCodec (LogicalModelType b) where
  codec :: JSONCodec (LogicalModelType b)
codec =
    Text
-> JSONCodec (LogicalModelType b) -> JSONCodec (LogicalModelType b)
forall input output.
Text -> ValueCodec input output -> ValueCodec input output
AC.CommentCodec
      (Text
"A type used in a Logical Model field")
      (JSONCodec (LogicalModelType b) -> JSONCodec (LogicalModelType b))
-> JSONCodec (LogicalModelType b) -> JSONCodec (LogicalModelType b)
forall a b. (a -> b) -> a -> b
$ JSONCodec (LogicalModelType b)
forall a. (FromJSON a, ToJSON a) => JSONCodec a
placeholderCodecViaJSON

instance (Backend b) => FromJSON (LogicalModelType b) where
  parseJSON :: Value -> Parser (LogicalModelType b)
parseJSON Value
j =
    (LogicalModelTypeScalar b -> LogicalModelType b
forall (b :: BackendType).
LogicalModelTypeScalar b -> LogicalModelType b
LogicalModelTypeScalar (LogicalModelTypeScalar b -> LogicalModelType b)
-> Parser (LogicalModelTypeScalar b) -> Parser (LogicalModelType b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (LogicalModelTypeScalar b)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
j)
      Parser (LogicalModelType b)
-> Parser (LogicalModelType b) -> Parser (LogicalModelType b)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (LogicalModelTypeArray b -> LogicalModelType b
forall (b :: BackendType).
LogicalModelTypeArray b -> LogicalModelType b
LogicalModelTypeArray (LogicalModelTypeArray b -> LogicalModelType b)
-> Parser (LogicalModelTypeArray b) -> Parser (LogicalModelType b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (LogicalModelTypeArray b)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
j)
      Parser (LogicalModelType b)
-> Parser (LogicalModelType b) -> Parser (LogicalModelType b)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (LogicalModelTypeReference -> LogicalModelType b
forall (b :: BackendType).
LogicalModelTypeReference -> LogicalModelType b
LogicalModelTypeReference (LogicalModelTypeReference -> LogicalModelType b)
-> Parser LogicalModelTypeReference -> Parser (LogicalModelType b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser LogicalModelTypeReference
forall a. FromJSON a => Value -> Parser a
parseJSON Value
j)

instance (Backend b) => ToJSON (LogicalModelType b) where
  toJSON :: LogicalModelType b -> Value
toJSON (LogicalModelTypeScalar LogicalModelTypeScalar b
t) = LogicalModelTypeScalar b -> Value
forall a. ToJSON a => a -> Value
toJSON LogicalModelTypeScalar b
t
  toJSON (LogicalModelTypeArray LogicalModelTypeArray b
t) = LogicalModelTypeArray b -> Value
forall a. ToJSON a => a -> Value
toJSON LogicalModelTypeArray b
t
  toJSON (LogicalModelTypeReference LogicalModelTypeReference
t) = LogicalModelTypeReference -> Value
forall a. ToJSON a => a -> Value
toJSON LogicalModelTypeReference
t

----

-- | a single field in a Logical Model
data LogicalModelField b = LogicalModelField
  { forall (b :: BackendType). LogicalModelField b -> Column b
lmfName :: Column b,
    forall (b :: BackendType).
LogicalModelField b -> LogicalModelType b
lmfType :: LogicalModelType b,
    forall (b :: BackendType). LogicalModelField b -> Maybe Text
lmfDescription :: Maybe Text
  }
  deriving ((forall x. LogicalModelField b -> Rep (LogicalModelField b) x)
-> (forall x. Rep (LogicalModelField b) x -> LogicalModelField b)
-> Generic (LogicalModelField b)
forall x. Rep (LogicalModelField b) x -> LogicalModelField b
forall x. LogicalModelField b -> Rep (LogicalModelField b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) x.
Rep (LogicalModelField b) x -> LogicalModelField b
forall (b :: BackendType) x.
LogicalModelField b -> Rep (LogicalModelField b) x
$cfrom :: forall (b :: BackendType) x.
LogicalModelField b -> Rep (LogicalModelField b) x
from :: forall x. LogicalModelField b -> Rep (LogicalModelField b) x
$cto :: forall (b :: BackendType) x.
Rep (LogicalModelField b) x -> LogicalModelField b
to :: forall x. Rep (LogicalModelField b) x -> LogicalModelField b
Generic)

data LogicalModelFieldSimple b = LogicalModelFieldSimple
  { forall (b :: BackendType). LogicalModelFieldSimple b -> Column b
lmfsName :: Column b,
    forall (b :: BackendType).
LogicalModelFieldSimple b -> ScalarType b
lmfsScalar :: ScalarType b,
    forall (b :: BackendType). LogicalModelFieldSimple b -> Bool
lmfsNullable :: Bool,
    forall (b :: BackendType). LogicalModelFieldSimple b -> Maybe Text
lmfsDescription :: Maybe Text
  }

-- | this codec is complicated because we want to support both the old scalar
-- encoded fields and our new separate type
instance (Backend b) => HasCodec (LogicalModelField b) where
  codec :: JSONCodec (LogicalModelField b)
codec = JSONCodec (LogicalModelField b)
-> JSONCodec (LogicalModelField b)
-> JSONCodec (LogicalModelField b)
forall context input output input'.
Codec context input output
-> Codec context input' output -> Codec context input output
AC.parseAlternative JSONCodec (LogicalModelField b)
newCodec JSONCodec (LogicalModelField b)
simpleCodecMappedToNew -- we always encode as `newCodec` but we try parsing with both
    where
      -- if we parse the old kind, convert it to the new exciting kind
      fromSimple :: LogicalModelFieldSimple b -> LogicalModelField b
      fromSimple :: LogicalModelFieldSimple b -> LogicalModelField b
fromSimple (LogicalModelFieldSimple {Column b
lmfsName :: forall (b :: BackendType). LogicalModelFieldSimple b -> Column b
lmfsName :: Column b
lmfsName, ScalarType b
lmfsScalar :: forall (b :: BackendType).
LogicalModelFieldSimple b -> ScalarType b
lmfsScalar :: ScalarType b
lmfsScalar, Bool
lmfsNullable :: forall (b :: BackendType). LogicalModelFieldSimple b -> Bool
lmfsNullable :: Bool
lmfsNullable, Maybe Text
lmfsDescription :: forall (b :: BackendType). LogicalModelFieldSimple b -> Maybe Text
lmfsDescription :: Maybe Text
lmfsDescription}) =
        LogicalModelField
          { lmfName :: Column b
lmfName = Column b
lmfsName,
            lmfDescription :: Maybe Text
lmfDescription = Maybe Text
lmfsDescription,
            lmfType :: LogicalModelType b
lmfType =
              LogicalModelTypeScalar b -> LogicalModelType b
forall (b :: BackendType).
LogicalModelTypeScalar b -> LogicalModelType b
LogicalModelTypeScalar
                ( LogicalModelTypeScalarC {lmtsScalar :: ScalarType b
lmtsScalar = ScalarType b
lmfsScalar, lmtsNullable :: Bool
lmtsNullable = Bool
lmfsNullable}
                )
          }

      -- try and convert the new kind to the old (this is partial, but
      -- shouldn't actually be used)
      toSimple :: LogicalModelField b -> LogicalModelFieldSimple b
toSimple
        ( LogicalModelField
            { Column b
lmfName :: forall (b :: BackendType). LogicalModelField b -> Column b
lmfName :: Column b
lmfName,
              Maybe Text
lmfDescription :: forall (b :: BackendType). LogicalModelField b -> Maybe Text
lmfDescription :: Maybe Text
lmfDescription,
              lmfType :: forall (b :: BackendType).
LogicalModelField b -> LogicalModelType b
lmfType = LogicalModelTypeScalar (LogicalModelTypeScalarC {ScalarType b
lmtsScalar :: forall (b :: BackendType). LogicalModelTypeScalar b -> ScalarType b
lmtsScalar :: ScalarType b
lmtsScalar, Bool
lmtsNullable :: forall (b :: BackendType). LogicalModelTypeScalar b -> Bool
lmtsNullable :: Bool
lmtsNullable})
            }
          ) =
          LogicalModelFieldSimple
            { lmfsName :: Column b
lmfsName = Column b
Column b
lmfName,
              lmfsScalar :: ScalarType b
lmfsScalar = ScalarType b
ScalarType b
lmtsScalar,
              lmfsNullable :: Bool
lmfsNullable = Bool
lmtsNullable,
              lmfsDescription :: Maybe Text
lmfsDescription = Maybe Text
lmfDescription
            }
      toSimple LogicalModelField b
_ = String -> LogicalModelFieldSimple b
forall a. HasCallStack => String -> a
error String
"Could not convert LogicalModelField to LogicalModelFieldSimple"

      simpleCodecMappedToNew :: AC.JSONCodec (LogicalModelField b)
      simpleCodecMappedToNew :: JSONCodec (LogicalModelField b)
simpleCodecMappedToNew = (LogicalModelFieldSimple b -> LogicalModelField b)
-> (LogicalModelField b -> LogicalModelFieldSimple b)
-> Codec
     Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
-> JSONCodec (LogicalModelField b)
forall oldOutput newOutput newInput oldInput context.
(oldOutput -> newOutput)
-> (newInput -> oldInput)
-> Codec context oldInput oldOutput
-> Codec context newInput newOutput
AC.dimapCodec LogicalModelFieldSimple b -> LogicalModelField b
fromSimple LogicalModelField b -> LogicalModelFieldSimple b
forall {b :: BackendType} {b :: BackendType}.
(Column b ~ Column b, ScalarType b ~ ScalarType b) =>
LogicalModelField b -> LogicalModelFieldSimple b
toSimple Codec Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
simpleCodec

      simpleCodec :: AC.JSONCodec (LogicalModelFieldSimple b)
      simpleCodec :: Codec Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
simpleCodec =
        -- this is the simpler old codec that did scalar types only
        Text
-> Codec
     Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
-> Codec
     Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
forall input output.
Text -> ValueCodec input output -> ValueCodec input output
AC.CommentCodec
          (Text
"A field of a logical model")
          (Codec
   Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
 -> Codec
      Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b))
-> Codec
     Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
-> Codec
     Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
forall a b. (a -> b) -> a -> b
$ Text
-> ObjectCodec
     (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
-> Codec
     Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
forall input output.
Text -> ObjectCodec input output -> ValueCodec input output
AC.object (forall (b :: BackendType). HasTag b => Text
backendPrefix @b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"LogicalModelField")
          (ObjectCodec
   (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
 -> Codec
      Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b))
-> ObjectCodec
     (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
-> Codec
     Value (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
forall a b. (a -> b) -> a -> b
$ Column b
-> ScalarType b -> Bool -> Maybe Text -> LogicalModelFieldSimple b
forall (b :: BackendType).
Column b
-> ScalarType b -> Bool -> Maybe Text -> LogicalModelFieldSimple b
LogicalModelFieldSimple
          (Column b
 -> ScalarType b -> Bool -> Maybe Text -> LogicalModelFieldSimple b)
-> Codec Object (LogicalModelFieldSimple b) (Column b)
-> Codec
     Object
     (LogicalModelFieldSimple b)
     (ScalarType b -> Bool -> Maybe Text -> LogicalModelFieldSimple b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Text -> ObjectCodec (Column b) (Column b)
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec output output
AC.requiredField Text
"name" Text
nameDoc
          ObjectCodec (Column b) (Column b)
-> (LogicalModelFieldSimple b -> Column b)
-> Codec Object (LogicalModelFieldSimple b) (Column b)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelFieldSimple b -> Column b
forall (b :: BackendType). LogicalModelFieldSimple b -> Column b
lmfsName
            Codec
  Object
  (LogicalModelFieldSimple b)
  (ScalarType b -> Bool -> Maybe Text -> LogicalModelFieldSimple b)
-> Codec Object (LogicalModelFieldSimple b) (ScalarType b)
-> Codec
     Object
     (LogicalModelFieldSimple b)
     (Bool -> Maybe Text -> LogicalModelFieldSimple b)
forall a b.
Codec Object (LogicalModelFieldSimple b) (a -> b)
-> Codec Object (LogicalModelFieldSimple b) a
-> Codec Object (LogicalModelFieldSimple b) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Text -> ObjectCodec (ScalarType b) (ScalarType b)
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec output output
AC.requiredField Text
"type" Text
typeDoc
          ObjectCodec (ScalarType b) (ScalarType b)
-> (LogicalModelFieldSimple b -> ScalarType b)
-> Codec Object (LogicalModelFieldSimple b) (ScalarType b)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelFieldSimple b -> ScalarType b
forall (b :: BackendType).
LogicalModelFieldSimple b -> ScalarType b
lmfsScalar
            Codec
  Object
  (LogicalModelFieldSimple b)
  (Bool -> Maybe Text -> LogicalModelFieldSimple b)
-> Codec Object (LogicalModelFieldSimple b) Bool
-> Codec
     Object
     (LogicalModelFieldSimple b)
     (Maybe Text -> LogicalModelFieldSimple b)
forall a b.
Codec Object (LogicalModelFieldSimple b) (a -> b)
-> Codec Object (LogicalModelFieldSimple b) a
-> Codec Object (LogicalModelFieldSimple b) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Bool -> Text -> ObjectCodec Bool Bool
forall output.
HasCodec output =>
Text -> output -> Text -> ObjectCodec output output
AC.optionalFieldWithDefault Text
"nullable" Bool
False Text
nullableDoc
          ObjectCodec Bool Bool
-> (LogicalModelFieldSimple b -> Bool)
-> Codec Object (LogicalModelFieldSimple b) Bool
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelFieldSimple b -> Bool
forall (b :: BackendType). LogicalModelFieldSimple b -> Bool
lmfsNullable
            Codec
  Object
  (LogicalModelFieldSimple b)
  (Maybe Text -> LogicalModelFieldSimple b)
-> Codec Object (LogicalModelFieldSimple b) (Maybe Text)
-> ObjectCodec
     (LogicalModelFieldSimple b) (LogicalModelFieldSimple b)
forall a b.
Codec Object (LogicalModelFieldSimple b) (a -> b)
-> Codec Object (LogicalModelFieldSimple b) a
-> Codec Object (LogicalModelFieldSimple b) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Text -> ObjectCodec (Maybe Text) (Maybe Text)
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec (Maybe output) (Maybe output)
AC.optionalField Text
"description" Text
descriptionDoc
          ObjectCodec (Maybe Text) (Maybe Text)
-> (LogicalModelFieldSimple b -> Maybe Text)
-> Codec Object (LogicalModelFieldSimple b) (Maybe Text)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelFieldSimple b -> Maybe Text
forall (b :: BackendType). LogicalModelFieldSimple b -> Maybe Text
lmfsDescription
        where
          nameDoc :: Text
nameDoc = Text
"Name of the field"
          nullableDoc :: Text
nullableDoc = Text
"Is field nullable or not?"
          typeDoc :: Text
typeDoc = Text
"Type of the field"
          descriptionDoc :: Text
descriptionDoc = Text
"Optional description of this field"

      newCodec :: JSONCodec (LogicalModelField b)
newCodec =
        -- the new codec which defers to LogicalModelType for all the
        -- complexities
        Text
-> JSONCodec (LogicalModelField b)
-> JSONCodec (LogicalModelField b)
forall input output.
Text -> ValueCodec input output -> ValueCodec input output
AC.CommentCodec
          (Text
"A field of a logical model")
          (JSONCodec (LogicalModelField b)
 -> JSONCodec (LogicalModelField b))
-> JSONCodec (LogicalModelField b)
-> JSONCodec (LogicalModelField b)
forall a b. (a -> b) -> a -> b
$ Text
-> ObjectCodec (LogicalModelField b) (LogicalModelField b)
-> JSONCodec (LogicalModelField b)
forall input output.
Text -> ObjectCodec input output -> ValueCodec input output
AC.object (forall (b :: BackendType). HasTag b => Text
backendPrefix @b Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"LogicalModelField")
          (ObjectCodec (LogicalModelField b) (LogicalModelField b)
 -> JSONCodec (LogicalModelField b))
-> ObjectCodec (LogicalModelField b) (LogicalModelField b)
-> JSONCodec (LogicalModelField b)
forall a b. (a -> b) -> a -> b
$ Column b -> LogicalModelType b -> Maybe Text -> LogicalModelField b
forall (b :: BackendType).
Column b -> LogicalModelType b -> Maybe Text -> LogicalModelField b
LogicalModelField
          (Column b
 -> LogicalModelType b -> Maybe Text -> LogicalModelField b)
-> Codec Object (LogicalModelField b) (Column b)
-> Codec
     Object
     (LogicalModelField b)
     (LogicalModelType b -> Maybe Text -> LogicalModelField b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Text -> ObjectCodec (Column b) (Column b)
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec output output
AC.requiredField Text
"name" Text
nameDoc
          ObjectCodec (Column b) (Column b)
-> (LogicalModelField b -> Column b)
-> Codec Object (LogicalModelField b) (Column b)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelField b -> Column b
forall (b :: BackendType). LogicalModelField b -> Column b
lmfName
            Codec
  Object
  (LogicalModelField b)
  (LogicalModelType b -> Maybe Text -> LogicalModelField b)
-> Codec Object (LogicalModelField b) (LogicalModelType b)
-> Codec
     Object (LogicalModelField b) (Maybe Text -> LogicalModelField b)
forall a b.
Codec Object (LogicalModelField b) (a -> b)
-> Codec Object (LogicalModelField b) a
-> Codec Object (LogicalModelField b) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text
-> Text -> ObjectCodec (LogicalModelType b) (LogicalModelType b)
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec output output
AC.requiredField Text
"type" Text
typeDoc
          ObjectCodec (LogicalModelType b) (LogicalModelType b)
-> (LogicalModelField b -> LogicalModelType b)
-> Codec Object (LogicalModelField b) (LogicalModelType b)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelField b -> LogicalModelType b
forall (b :: BackendType).
LogicalModelField b -> LogicalModelType b
lmfType
            Codec
  Object (LogicalModelField b) (Maybe Text -> LogicalModelField b)
-> Codec Object (LogicalModelField b) (Maybe Text)
-> ObjectCodec (LogicalModelField b) (LogicalModelField b)
forall a b.
Codec Object (LogicalModelField b) (a -> b)
-> Codec Object (LogicalModelField b) a
-> Codec Object (LogicalModelField b) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Text -> ObjectCodec (Maybe Text) (Maybe Text)
forall output.
HasCodec output =>
Text -> Text -> ObjectCodec (Maybe output) (Maybe output)
AC.optionalField Text
"description" Text
descriptionDoc
          ObjectCodec (Maybe Text) (Maybe Text)
-> (LogicalModelField b -> Maybe Text)
-> Codec Object (LogicalModelField b) (Maybe Text)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= LogicalModelField b -> Maybe Text
forall (b :: BackendType). LogicalModelField b -> Maybe Text
lmfDescription
        where
          nameDoc :: Text
nameDoc = Text
"Name of the field"
          typeDoc :: Text
typeDoc = Text
"Type of the field"
          descriptionDoc :: Text
descriptionDoc = Text
"Optional description of this field"

deriving via
  (AC.Autodocodec (LogicalModelField b))
  instance
    (Backend b) => (ToJSON (LogicalModelField b))

deriving via
  (AC.Autodocodec (LogicalModelField b))
  instance
    (Backend b) => FromJSON (LogicalModelField b)

deriving stock instance (Backend b) => Eq (LogicalModelField b)

deriving stock instance (Backend b) => Show (LogicalModelField b)

instance (Backend b) => Hashable (LogicalModelField b)

instance (Backend b) => NFData (LogicalModelField b)

-- we parse in as an array of NullableScalarTypeFromArray and then turn into
-- InsOrdHashMap because JSON objects cannot be depended on for ordering
logicalModelFieldMapCodec ::
  forall b.
  (Backend b) =>
  AC.Codec
    Value
    (InsOrdHashMap.InsOrdHashMap (Column b) (LogicalModelField b))
    (InsOrdHashMap.InsOrdHashMap (Column b) (LogicalModelField b))
logicalModelFieldMapCodec :: forall (b :: BackendType).
Backend b =>
Codec
  Value
  (InsOrdHashMap (Column b) (LogicalModelField b))
  (InsOrdHashMap (Column b) (LogicalModelField b))
logicalModelFieldMapCodec =
  ([LogicalModelField b]
 -> InsOrdHashMap (Column b) (LogicalModelField b))
-> (InsOrdHashMap (Column b) (LogicalModelField b)
    -> [LogicalModelField b])
-> Codec Value [LogicalModelField b] [LogicalModelField b]
-> Codec
     Value
     (InsOrdHashMap (Column b) (LogicalModelField b))
     (InsOrdHashMap (Column b) (LogicalModelField b))
forall oldOutput newOutput newInput oldInput context.
(oldOutput -> newOutput)
-> (newInput -> oldInput)
-> Codec context oldInput oldOutput
-> Codec context newInput newOutput
AC.dimapCodec
    ( [(Column b, LogicalModelField b)]
-> InsOrdHashMap (Column b) (LogicalModelField b)
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
InsOrdHashMap.fromList
        ([(Column b, LogicalModelField b)]
 -> InsOrdHashMap (Column b) (LogicalModelField b))
-> ([LogicalModelField b] -> [(Column b, LogicalModelField b)])
-> [LogicalModelField b]
-> InsOrdHashMap (Column b) (LogicalModelField b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LogicalModelField b -> (Column b, LogicalModelField b))
-> [LogicalModelField b] -> [(Column b, LogicalModelField b)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
          ( \LogicalModelField b
lmf -> (LogicalModelField b -> Column b
forall (b :: BackendType). LogicalModelField b -> Column b
lmfName LogicalModelField b
lmf, LogicalModelField b
lmf)
          )
    )
    ( ((Column b, LogicalModelField b) -> LogicalModelField b)
-> [(Column b, LogicalModelField b)] -> [LogicalModelField b]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Column b, LogicalModelField b) -> LogicalModelField b
forall a b. (a, b) -> b
snd ([(Column b, LogicalModelField b)] -> [LogicalModelField b])
-> (InsOrdHashMap (Column b) (LogicalModelField b)
    -> [(Column b, LogicalModelField b)])
-> InsOrdHashMap (Column b) (LogicalModelField b)
-> [LogicalModelField b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsOrdHashMap (Column b) (LogicalModelField b)
-> [(Column b, LogicalModelField b)]
forall k v. InsOrdHashMap k v -> [(k, v)]
InsOrdHashMap.toList
    )
    (forall value. HasCodec value => JSONCodec value
AC.codec @[LogicalModelField b])