mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 17:31:56 +03:00
refactor(tests): Remove use of unsafeCoerce
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5682 GitOrigin-RevId: 78ac1482977f427148e7675e45ff9c515db02b68
This commit is contained in:
parent
bf91655c30
commit
8bc34e12e3
@ -34,7 +34,12 @@
|
|||||||
-- performed by "Hasura.GraphQL.Execute.Resolve", but for fragment definitions
|
-- performed by "Hasura.GraphQL.Execute.Resolve", but for fragment definitions
|
||||||
-- rather than variables.
|
-- rather than variables.
|
||||||
module Hasura.GraphQL.Execute.Inline
|
module Hasura.GraphQL.Execute.Inline
|
||||||
( inlineSelectionSet,
|
( InlineMT,
|
||||||
|
InlineM,
|
||||||
|
inlineSelectionSet,
|
||||||
|
inlineField,
|
||||||
|
runInlineMT,
|
||||||
|
runInlineM,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@ -74,6 +79,34 @@ type MonadInline m =
|
|||||||
MonadState InlineState m
|
MonadState InlineState m
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type InlineMT m a = MonadError QErr m => (StateT InlineState (ReaderT InlineEnv m)) a
|
||||||
|
|
||||||
|
type InlineM a = InlineMT (Except QErr) a
|
||||||
|
|
||||||
|
{-# INLINE runInlineMT #-}
|
||||||
|
runInlineMT ::
|
||||||
|
forall m a.
|
||||||
|
(MonadError QErr m) =>
|
||||||
|
HashMap Name FragmentDefinition ->
|
||||||
|
InlineMT m a ->
|
||||||
|
m a
|
||||||
|
runInlineMT uniqueFragmentDefinitions =
|
||||||
|
flip
|
||||||
|
runReaderT
|
||||||
|
InlineEnv
|
||||||
|
{ _ieFragmentDefinitions = uniqueFragmentDefinitions,
|
||||||
|
_ieFragmentStack = []
|
||||||
|
}
|
||||||
|
. flip evalStateT InlineState {_isFragmentCache = mempty}
|
||||||
|
|
||||||
|
{-# INLINE runInlineM #-}
|
||||||
|
runInlineM ::
|
||||||
|
forall a.
|
||||||
|
HashMap Name FragmentDefinition ->
|
||||||
|
InlineM a ->
|
||||||
|
Either QErr a
|
||||||
|
runInlineM fragments = runExcept . runInlineMT fragments
|
||||||
|
|
||||||
-- | Inlines all fragment spreads in a 'SelectionSet'; see the module
|
-- | Inlines all fragment spreads in a 'SelectionSet'; see the module
|
||||||
-- documentation for "Hasura.GraphQL.Execute.Inline" for details.
|
-- documentation for "Hasura.GraphQL.Execute.Inline" for details.
|
||||||
inlineSelectionSet ::
|
inlineSelectionSet ::
|
||||||
@ -106,6 +139,8 @@ inlineSelectionSet fragmentDefinitions selectionSet = do
|
|||||||
Set.toList $
|
Set.toList $
|
||||||
Set.difference definedFragmentNames usedFragmentNames
|
Set.difference definedFragmentNames usedFragmentNames
|
||||||
)
|
)
|
||||||
|
-- The below code is a manual inlining of 'runInlineMT', as appearently the
|
||||||
|
-- inlining optimization does not trigger, even with the INLINE pragma.
|
||||||
traverse inlineSelection selectionSet
|
traverse inlineSelection selectionSet
|
||||||
& flip evalStateT InlineState {_isFragmentCache = mempty}
|
& flip evalStateT InlineState {_isFragmentCache = mempty}
|
||||||
& flip
|
& flip
|
||||||
@ -128,11 +163,8 @@ inlineSelection ::
|
|||||||
MonadInline m =>
|
MonadInline m =>
|
||||||
Selection FragmentSpread Name ->
|
Selection FragmentSpread Name ->
|
||||||
m (Selection NoFragments Name)
|
m (Selection NoFragments Name)
|
||||||
inlineSelection (SelectionField field@Field {_fSelectionSet}) =
|
inlineSelection (SelectionField field) =
|
||||||
withPathK "selectionSet" $
|
withPathK "selectionSet" $ SelectionField <$> inlineField field
|
||||||
withPathK (unName $ _fName field) $ do
|
|
||||||
selectionSet <- traverse inlineSelection _fSelectionSet
|
|
||||||
pure $! SelectionField field {_fSelectionSet = selectionSet}
|
|
||||||
inlineSelection (SelectionFragmentSpread spread) =
|
inlineSelection (SelectionFragmentSpread spread) =
|
||||||
withPathK "selectionSet" $
|
withPathK "selectionSet" $
|
||||||
SelectionInlineFragment <$> inlineFragmentSpread spread
|
SelectionInlineFragment <$> inlineFragmentSpread spread
|
||||||
@ -140,6 +172,12 @@ inlineSelection (SelectionInlineFragment fragment@InlineFragment {_ifSelectionSe
|
|||||||
selectionSet <- traverse inlineSelection _ifSelectionSet
|
selectionSet <- traverse inlineSelection _ifSelectionSet
|
||||||
pure $! SelectionInlineFragment fragment {_ifSelectionSet = selectionSet}
|
pure $! SelectionInlineFragment fragment {_ifSelectionSet = selectionSet}
|
||||||
|
|
||||||
|
{-# INLINE inlineField #-}
|
||||||
|
inlineField :: MonadInline m => Field FragmentSpread Name -> m (Field NoFragments Name)
|
||||||
|
inlineField field@(Field {_fSelectionSet}) = withPathK (unName $ _fName field) $ do
|
||||||
|
selectionSet <- traverse inlineSelection _fSelectionSet
|
||||||
|
pure $! field {_fSelectionSet = selectionSet}
|
||||||
|
|
||||||
inlineFragmentSpread ::
|
inlineFragmentSpread ::
|
||||||
MonadInline m =>
|
MonadInline m =>
|
||||||
FragmentSpread Name ->
|
FragmentSpread Name ->
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
-- | QuasiQuoter for parsing GraphQL fields in tests. See 'field' for details.
|
-- | QuasiQuoter for parsing GraphQL fields in tests. See 'field' for details.
|
||||||
module Test.Parser.Field (field) where
|
module Test.Parser.Field (field) where
|
||||||
|
|
||||||
|
import Control.Monad.Trans.Except
|
||||||
import Data.Attoparsec.Text qualified as Parser
|
import Data.Attoparsec.Text qualified as Parser
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
|
import Hasura.Base.Error (showQErr)
|
||||||
|
import Hasura.GraphQL.Execute.Inline (inlineField, runInlineM)
|
||||||
import Hasura.GraphQL.Parser.Variable
|
import Hasura.GraphQL.Parser.Variable
|
||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
import Language.GraphQL.Draft.Parser qualified as GraphQL
|
import Language.GraphQL.Draft.Parser qualified as GraphQL
|
||||||
@ -10,11 +13,8 @@ import Language.GraphQL.Draft.Syntax qualified as GraphQL
|
|||||||
import Language.Haskell.TH.Lib (ExpQ)
|
import Language.Haskell.TH.Lib (ExpQ)
|
||||||
import Language.Haskell.TH.Quote
|
import Language.Haskell.TH.Quote
|
||||||
import Language.Haskell.TH.Syntax qualified as TH
|
import Language.Haskell.TH.Syntax qualified as TH
|
||||||
import Unsafe.Coerce (unsafeCoerce)
|
|
||||||
|
|
||||||
-- | Warning: we are currently using unsafe coercions to convert the field. This
|
-- | Quasi-Quoter for GraphQL fields.
|
||||||
-- seems to work for now, but beware.
|
|
||||||
--
|
|
||||||
-- Example usage:
|
-- Example usage:
|
||||||
-- > [GQL.field|
|
-- > [GQL.field|
|
||||||
-- > update_artist(
|
-- > update_artist(
|
||||||
@ -27,21 +27,22 @@ import Unsafe.Coerce (unsafeCoerce)
|
|||||||
field :: QuasiQuoter
|
field :: QuasiQuoter
|
||||||
field =
|
field =
|
||||||
QuasiQuoter
|
QuasiQuoter
|
||||||
{ quoteExp = evalFieldGQL,
|
{ quoteExp = fieldExp,
|
||||||
quotePat = \_ -> fail "invalid",
|
quotePat = \_ -> fail "invalid",
|
||||||
quoteType = \_ -> fail "invalid",
|
quoteType = \_ -> fail "invalid",
|
||||||
quoteDec = \_ -> fail "invalid"
|
quoteDec = \_ -> fail "invalid"
|
||||||
}
|
}
|
||||||
|
|
||||||
evalFieldGQL :: String -> ExpQ
|
|
||||||
evalFieldGQL = either fail TH.lift . go
|
|
||||||
where
|
where
|
||||||
-- Note: @skipSpace@ is used here to allow trailing whitespace in the QQ.
|
fieldExp :: String -> ExpQ
|
||||||
go :: String -> Either String (GraphQL.Field GraphQL.NoFragments Variable)
|
fieldExp input = do
|
||||||
go =
|
either fail TH.lift $
|
||||||
fmap fixField
|
runExcept $ do
|
||||||
. Parser.parseOnly (Parser.skipSpace *> GraphQL.field @GraphQL.Name)
|
parsed <- hoistEither $ Parser.parseOnly (Parser.skipSpace *> GraphQL.field @GraphQL.Name) . T.pack $ input
|
||||||
. T.pack
|
fixField parsed
|
||||||
|
|
||||||
fixField :: GraphQL.Field GraphQL.FragmentSpread GraphQL.Name -> GraphQL.Field GraphQL.NoFragments Variable
|
-- A parsed field can contain both fragments and variables.
|
||||||
fixField = unsafeCoerce
|
-- We support neither yet.
|
||||||
|
fixField :: GraphQL.Field GraphQL.FragmentSpread GraphQL.Name -> Except String (GraphQL.Field GraphQL.NoFragments Variable)
|
||||||
|
fixField f = do
|
||||||
|
x <- except $ mapLeft (T.unpack . showQErr) $ runInlineM mempty . inlineField $ f
|
||||||
|
traverse (throwE . ("Variables are not supported in tests yet: " ++) . show) x
|
||||||
|
Loading…
Reference in New Issue
Block a user