{-# LANGUAGE DeriveAnyClass #-}

module Hasura.RQL.Types.DataConnector
  ( DataConnectorName,
    unDataConnectorName,
    mkDataConnectorName,
  )
where

-- This file is only for Data Connector types that must be referenced in
-- `RQL.Types`

import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
import Data.Aeson qualified as J
import Data.Data (Typeable)
import Data.Text qualified as Text
import Data.Text.Extended (ToTxt (..))
import Data.Text.NonEmpty (NonEmptyText, mkNonEmptyTextUnsafe)
import Hasura.Prelude
import Language.GraphQL.Draft.Syntax qualified as GQL
import Witch qualified

-- | Note: Currently you should not use underscores in this name.
--         This should be enforced in instances, and the `mkDataConnectorName`
--         smart constructor is available to assist.
newtype DataConnectorName = DataConnectorName {DataConnectorName -> Name
unDataConnectorName :: GQL.Name}
  deriving stock (DataConnectorName -> DataConnectorName -> Bool
(DataConnectorName -> DataConnectorName -> Bool)
-> (DataConnectorName -> DataConnectorName -> Bool)
-> Eq DataConnectorName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DataConnectorName -> DataConnectorName -> Bool
== :: DataConnectorName -> DataConnectorName -> Bool
$c/= :: DataConnectorName -> DataConnectorName -> Bool
/= :: DataConnectorName -> DataConnectorName -> Bool
Eq, Eq DataConnectorName
Eq DataConnectorName
-> (DataConnectorName -> DataConnectorName -> Ordering)
-> (DataConnectorName -> DataConnectorName -> Bool)
-> (DataConnectorName -> DataConnectorName -> Bool)
-> (DataConnectorName -> DataConnectorName -> Bool)
-> (DataConnectorName -> DataConnectorName -> Bool)
-> (DataConnectorName -> DataConnectorName -> DataConnectorName)
-> (DataConnectorName -> DataConnectorName -> DataConnectorName)
-> Ord DataConnectorName
DataConnectorName -> DataConnectorName -> Bool
DataConnectorName -> DataConnectorName -> Ordering
DataConnectorName -> DataConnectorName -> DataConnectorName
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 :: DataConnectorName -> DataConnectorName -> Ordering
compare :: DataConnectorName -> DataConnectorName -> Ordering
$c< :: DataConnectorName -> DataConnectorName -> Bool
< :: DataConnectorName -> DataConnectorName -> Bool
$c<= :: DataConnectorName -> DataConnectorName -> Bool
<= :: DataConnectorName -> DataConnectorName -> Bool
$c> :: DataConnectorName -> DataConnectorName -> Bool
> :: DataConnectorName -> DataConnectorName -> Bool
$c>= :: DataConnectorName -> DataConnectorName -> Bool
>= :: DataConnectorName -> DataConnectorName -> Bool
$cmax :: DataConnectorName -> DataConnectorName -> DataConnectorName
max :: DataConnectorName -> DataConnectorName -> DataConnectorName
$cmin :: DataConnectorName -> DataConnectorName -> DataConnectorName
min :: DataConnectorName -> DataConnectorName -> DataConnectorName
Ord, Int -> DataConnectorName -> ShowS
[DataConnectorName] -> ShowS
DataConnectorName -> String
(Int -> DataConnectorName -> ShowS)
-> (DataConnectorName -> String)
-> ([DataConnectorName] -> ShowS)
-> Show DataConnectorName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DataConnectorName -> ShowS
showsPrec :: Int -> DataConnectorName -> ShowS
$cshow :: DataConnectorName -> String
show :: DataConnectorName -> String
$cshowList :: [DataConnectorName] -> ShowS
showList :: [DataConnectorName] -> ShowS
Show, Typeable, (forall x. DataConnectorName -> Rep DataConnectorName x)
-> (forall x. Rep DataConnectorName x -> DataConnectorName)
-> Generic DataConnectorName
forall x. Rep DataConnectorName x -> DataConnectorName
forall x. DataConnectorName -> Rep DataConnectorName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DataConnectorName -> Rep DataConnectorName x
from :: forall x. DataConnectorName -> Rep DataConnectorName x
$cto :: forall x. Rep DataConnectorName x -> DataConnectorName
to :: forall x. Rep DataConnectorName x -> DataConnectorName
Generic)
  deriving newtype ([DataConnectorName] -> Value
[DataConnectorName] -> Encoding
DataConnectorName -> Value
DataConnectorName -> Encoding
(DataConnectorName -> Value)
-> (DataConnectorName -> Encoding)
-> ([DataConnectorName] -> Value)
-> ([DataConnectorName] -> Encoding)
-> ToJSON DataConnectorName
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: DataConnectorName -> Value
toJSON :: DataConnectorName -> Value
$ctoEncoding :: DataConnectorName -> Encoding
toEncoding :: DataConnectorName -> Encoding
$ctoJSONList :: [DataConnectorName] -> Value
toJSONList :: [DataConnectorName] -> Value
$ctoEncodingList :: [DataConnectorName] -> Encoding
toEncodingList :: [DataConnectorName] -> Encoding
ToJSON, FromJSONKeyFunction [DataConnectorName]
FromJSONKeyFunction DataConnectorName
FromJSONKeyFunction DataConnectorName
-> FromJSONKeyFunction [DataConnectorName]
-> FromJSONKey DataConnectorName
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
$cfromJSONKey :: FromJSONKeyFunction DataConnectorName
fromJSONKey :: FromJSONKeyFunction DataConnectorName
$cfromJSONKeyList :: FromJSONKeyFunction [DataConnectorName]
fromJSONKeyList :: FromJSONKeyFunction [DataConnectorName]
FromJSONKey, ToJSONKeyFunction [DataConnectorName]
ToJSONKeyFunction DataConnectorName
ToJSONKeyFunction DataConnectorName
-> ToJSONKeyFunction [DataConnectorName]
-> ToJSONKey DataConnectorName
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
$ctoJSONKey :: ToJSONKeyFunction DataConnectorName
toJSONKey :: ToJSONKeyFunction DataConnectorName
$ctoJSONKeyList :: ToJSONKeyFunction [DataConnectorName]
toJSONKeyList :: ToJSONKeyFunction [DataConnectorName]
ToJSONKey, Eq DataConnectorName
Eq DataConnectorName
-> (Int -> DataConnectorName -> Int)
-> (DataConnectorName -> Int)
-> Hashable DataConnectorName
Int -> DataConnectorName -> Int
DataConnectorName -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> DataConnectorName -> Int
hashWithSalt :: Int -> DataConnectorName -> Int
$chash :: DataConnectorName -> Int
hash :: DataConnectorName -> Int
Hashable, DataConnectorName -> Text
(DataConnectorName -> Text) -> ToTxt DataConnectorName
forall a. (a -> Text) -> ToTxt a
$ctoTxt :: DataConnectorName -> Text
toTxt :: DataConnectorName -> Text
ToTxt)
  deriving anyclass (DataConnectorName -> ()
(DataConnectorName -> ()) -> NFData DataConnectorName
forall a. (a -> ()) -> NFData a
$crnf :: DataConnectorName -> ()
rnf :: DataConnectorName -> ()
NFData)

instance FromJSON DataConnectorName where
  parseJSON :: Value -> Parser DataConnectorName
parseJSON Value
v = (Either String DataConnectorName
-> (String -> Parser DataConnectorName) -> Parser DataConnectorName
forall (m :: * -> *) e a.
Applicative m =>
Either e a -> (e -> m a) -> m a
`onLeft` String -> Parser DataConnectorName
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail) (Either String DataConnectorName -> Parser DataConnectorName)
-> Parser (Either String DataConnectorName)
-> Parser DataConnectorName
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Name -> Either String DataConnectorName
mkDataConnectorName (Name -> Either String DataConnectorName)
-> Parser Name -> Parser (Either String DataConnectorName)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Name
forall a. FromJSON a => Value -> Parser a
J.parseJSON Value
v)

mkDataConnectorName :: GQL.Name -> Either String DataConnectorName
mkDataConnectorName :: Name -> Either String DataConnectorName
mkDataConnectorName Name
n =
  if (Char
'_' Char -> Text -> Bool
`Text.elem` Name -> Text
GQL.unName Name
n)
    then -- Could return other errors in future.
      String -> Either String DataConnectorName
forall a b. a -> Either a b
Left String
"DataConnectorName may not contain underscores."
    else DataConnectorName -> Either String DataConnectorName
forall a b. b -> Either a b
Right (Name -> DataConnectorName
DataConnectorName Name
n)

instance Witch.From DataConnectorName NonEmptyText where
  from :: DataConnectorName -> NonEmptyText
from = Text -> NonEmptyText
mkNonEmptyTextUnsafe (Text -> NonEmptyText)
-> (DataConnectorName -> Text) -> DataConnectorName -> NonEmptyText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Text
GQL.unName (Name -> Text)
-> (DataConnectorName -> Name) -> DataConnectorName -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DataConnectorName -> Name
unDataConnectorName -- mkNonEmptyTextUnsafe is safe here since GQL.Name is never empty

instance Witch.From DataConnectorName Text where
  from :: DataConnectorName -> Text
from = Name -> Text
GQL.unName (Name -> Text)
-> (DataConnectorName -> Name) -> DataConnectorName -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DataConnectorName -> Name
unDataConnectorName