summaryrefslogtreecommitdiff
path: root/src/Language/GraphQL/Execute/Directive.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Language/GraphQL/Execute/Directive.hs')
-rw-r--r--src/Language/GraphQL/Execute/Directive.hs50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/Language/GraphQL/Execute/Directive.hs b/src/Language/GraphQL/Execute/Directive.hs
new file mode 100644
index 0000000..733b6cf
--- /dev/null
+++ b/src/Language/GraphQL/Execute/Directive.hs
@@ -0,0 +1,50 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Language.GraphQL.Execute.Directive
+ ( selection
+ ) where
+
+import qualified Data.HashMap.Strict as HashMap
+import Language.GraphQL.AST.Core
+
+-- | Directive processing status.
+data Status
+ = Skip -- ^ Skip the selection and stop directive processing
+ | Include Directive -- ^ The directive was processed, try other handlers
+ | Continue Directive -- ^ Directive handler mismatch, try other handlers
+
+-- | Takes a list of directives, handles supported directives and excludes them
+-- from the result. If the selection should be skipped, returns 'Nothing'.
+selection :: [Directive] -> Maybe [Directive]
+selection = foldr go (Just [])
+ where
+ go directive' directives' =
+ case (skip . include) (Continue directive') of
+ (Include _) -> directives'
+ Skip -> Nothing
+ (Continue x) -> (x :) <$> directives'
+
+handle :: (Directive -> Status) -> Status -> Status
+handle _ Skip = Skip
+handle handler (Continue directive) = handler directive
+handle handler (Include directive) = handler directive
+
+-- * Directive implementations
+
+skip :: Status -> Status
+skip = handle skip'
+ where
+ skip' directive'@(Directive "skip" (Arguments arguments)) =
+ case HashMap.lookup "if" arguments of
+ (Just (Boolean True)) -> Skip
+ _ -> Include directive'
+ skip' directive' = Continue directive'
+
+include :: Status -> Status
+include = handle include'
+ where
+ include' directive'@(Directive "include" (Arguments arguments)) =
+ case HashMap.lookup "if" arguments of
+ (Just (Boolean True)) -> Include directive'
+ _ -> Skip
+ include' directive' = Continue directive'