2019-08-02 13:52:51 +02:00
|
|
|
{-# LANGUAGE ExplicitForAll #-}
|
2020-07-11 06:34:10 +02:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE LambdaCase #-}
|
2019-08-02 13:52:51 +02:00
|
|
|
|
2019-08-05 09:00:11 +02:00
|
|
|
-- | This module defines a minifier and a printer for the @GraphQL@ language.
|
2019-11-03 10:42:10 +01:00
|
|
|
module Language.GraphQL.AST.Encoder
|
2019-08-03 23:57:27 +02:00
|
|
|
( Formatter
|
2019-07-31 05:40:17 +02:00
|
|
|
, definition
|
2019-08-14 08:49:07 +02:00
|
|
|
, directive
|
2019-07-27 07:19:21 +02:00
|
|
|
, document
|
2019-08-03 23:57:27 +02:00
|
|
|
, minified
|
|
|
|
, pretty
|
2019-08-13 07:24:05 +02:00
|
|
|
, type'
|
|
|
|
, value
|
2019-07-14 05:58:05 +02:00
|
|
|
) where
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
import Data.Char (ord)
|
2017-01-28 18:15:14 +01:00
|
|
|
import Data.Foldable (fold)
|
2019-12-20 07:58:09 +01:00
|
|
|
import qualified Data.List.NonEmpty as NonEmpty
|
|
|
|
import Data.Text (Text)
|
|
|
|
import qualified Data.Text as Text
|
|
|
|
import qualified Data.Text.Lazy as Lazy (Text)
|
|
|
|
import qualified Data.Text.Lazy as Lazy.Text
|
2019-12-21 09:16:41 +01:00
|
|
|
import Data.Text.Lazy.Builder (Builder)
|
2019-12-19 06:59:27 +01:00
|
|
|
import qualified Data.Text.Lazy.Builder as Builder
|
2019-12-20 07:58:09 +01:00
|
|
|
import Data.Text.Lazy.Builder.Int (decimal, hexadecimal)
|
2019-08-05 09:00:11 +02:00
|
|
|
import Data.Text.Lazy.Builder.RealFloat (realFloat)
|
2019-12-26 13:00:47 +01:00
|
|
|
import Language.GraphQL.AST.Document
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2019-11-23 09:49:12 +01:00
|
|
|
-- | Instructs the encoder whether the GraphQL document should be minified or
|
|
|
|
-- pretty printed.
|
|
|
|
--
|
|
|
|
-- Use 'pretty' or 'minified' to construct the formatter.
|
2019-07-31 05:40:17 +02:00
|
|
|
data Formatter
|
|
|
|
= Minified
|
2019-08-03 23:57:27 +02:00
|
|
|
| Pretty Word
|
|
|
|
|
2019-09-25 05:35:36 +02:00
|
|
|
-- | Constructs a formatter for pretty printing.
|
2019-08-03 23:57:27 +02:00
|
|
|
pretty :: Formatter
|
|
|
|
pretty = Pretty 0
|
|
|
|
|
2019-09-25 05:35:36 +02:00
|
|
|
-- | Constructs a formatter for minifying.
|
2019-08-03 23:57:27 +02:00
|
|
|
minified :: Formatter
|
|
|
|
minified = Minified
|
2019-07-31 05:40:17 +02:00
|
|
|
|
2019-12-26 13:00:47 +01:00
|
|
|
-- | Converts a Document' into a string.
|
|
|
|
document :: Formatter -> Document -> Lazy.Text
|
2019-07-31 05:40:17 +02:00
|
|
|
document formatter defs
|
2019-12-20 07:58:09 +01:00
|
|
|
| Pretty _ <- formatter = Lazy.Text.intercalate "\n" encodeDocument
|
|
|
|
| Minified <-formatter = Lazy.Text.snoc (mconcat encodeDocument) '\n'
|
2019-07-31 05:40:17 +02:00
|
|
|
where
|
2019-12-25 06:45:29 +01:00
|
|
|
encodeDocument = foldr executableDefinition [] defs
|
2020-08-25 21:03:42 +02:00
|
|
|
executableDefinition (ExecutableDefinition executableDefinition') acc =
|
|
|
|
definition formatter executableDefinition' : acc
|
2019-12-26 13:00:47 +01:00
|
|
|
executableDefinition _ acc = acc
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
-- | Converts a t'ExecutableDefinition' into a string.
|
2019-12-26 13:00:47 +01:00
|
|
|
definition :: Formatter -> ExecutableDefinition -> Lazy.Text
|
2019-07-31 05:40:17 +02:00
|
|
|
definition formatter x
|
2019-12-20 07:58:09 +01:00
|
|
|
| Pretty _ <- formatter = Lazy.Text.snoc (encodeDefinition x) '\n'
|
2019-07-31 05:40:17 +02:00
|
|
|
| Minified <- formatter = encodeDefinition x
|
2019-07-27 07:19:21 +02:00
|
|
|
where
|
2020-05-22 10:11:48 +02:00
|
|
|
encodeDefinition (DefinitionOperation operation)
|
2019-07-31 05:40:17 +02:00
|
|
|
= operationDefinition formatter operation
|
2020-05-22 10:11:48 +02:00
|
|
|
encodeDefinition (DefinitionFragment fragment)
|
2019-07-31 05:40:17 +02:00
|
|
|
= fragmentDefinition formatter fragment
|
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
-- | Converts a 'OperationDefinition into a string.
|
|
|
|
operationDefinition :: Formatter -> OperationDefinition -> Lazy.Text
|
2020-07-11 06:34:10 +02:00
|
|
|
operationDefinition formatter = \case
|
2020-08-25 21:03:42 +02:00
|
|
|
SelectionSet sels _ -> selectionSet formatter sels
|
|
|
|
OperationDefinition Query name vars dirs sels _ ->
|
2020-07-11 06:34:10 +02:00
|
|
|
"query " <> node formatter name vars dirs sels
|
2020-08-25 21:03:42 +02:00
|
|
|
OperationDefinition Mutation name vars dirs sels _ ->
|
2020-07-11 06:34:10 +02:00
|
|
|
"mutation " <> node formatter name vars dirs sels
|
2020-08-25 21:03:42 +02:00
|
|
|
OperationDefinition Subscription name vars dirs sels _ ->
|
2020-07-11 06:34:10 +02:00
|
|
|
"subscription " <> node formatter name vars dirs sels
|
2019-07-31 05:40:17 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
-- | Converts a Query or Mutation into a string.
|
2019-12-20 07:58:09 +01:00
|
|
|
node :: Formatter ->
|
2020-05-22 10:11:48 +02:00
|
|
|
Maybe Name ->
|
|
|
|
[VariableDefinition] ->
|
|
|
|
[Directive] ->
|
|
|
|
SelectionSet ->
|
2019-12-20 07:58:09 +01:00
|
|
|
Lazy.Text
|
2019-07-31 05:40:17 +02:00
|
|
|
node formatter name vars dirs sels
|
2019-12-20 07:58:09 +01:00
|
|
|
= Lazy.Text.fromStrict (fold name)
|
2019-08-02 13:52:51 +02:00
|
|
|
<> optempty (variableDefinitions formatter) vars
|
|
|
|
<> optempty (directives formatter) dirs
|
|
|
|
<> eitherFormat formatter " " mempty
|
2019-07-31 05:40:17 +02:00
|
|
|
<> selectionSet formatter sels
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
variableDefinitions :: Formatter -> [VariableDefinition] -> Lazy.Text
|
2019-08-02 13:52:51 +02:00
|
|
|
variableDefinitions formatter
|
|
|
|
= parensCommas formatter $ variableDefinition formatter
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
variableDefinition :: Formatter -> VariableDefinition -> Lazy.Text
|
2020-09-19 18:18:26 +02:00
|
|
|
variableDefinition formatter (VariableDefinition var ty defaultValue' _)
|
2019-08-02 13:52:51 +02:00
|
|
|
= variable var
|
|
|
|
<> eitherFormat formatter ": " ":"
|
2019-08-13 07:24:05 +02:00
|
|
|
<> type' ty
|
2020-05-22 10:11:48 +02:00
|
|
|
<> maybe mempty (defaultValue formatter) defaultValue'
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
defaultValue :: Formatter -> ConstValue -> Lazy.Text
|
2019-08-02 13:52:51 +02:00
|
|
|
defaultValue formatter val
|
|
|
|
= eitherFormat formatter " = " "="
|
2020-05-22 10:11:48 +02:00
|
|
|
<> value formatter (fromConstValue val)
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
variable :: Name -> Lazy.Text
|
2019-12-20 07:58:09 +01:00
|
|
|
variable var = "$" <> Lazy.Text.fromStrict var
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
selectionSet :: Formatter -> SelectionSet -> Lazy.Text
|
2019-08-03 23:57:27 +02:00
|
|
|
selectionSet formatter
|
|
|
|
= bracesList formatter (selection formatter)
|
|
|
|
. NonEmpty.toList
|
2017-01-28 18:15:14 +01:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
selectionSetOpt :: Formatter -> SelectionSetOpt -> Lazy.Text
|
2019-08-03 23:57:27 +02:00
|
|
|
selectionSetOpt formatter = bracesList formatter $ selection formatter
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-03-29 15:56:07 +02:00
|
|
|
indentSymbol :: Lazy.Text
|
|
|
|
indentSymbol = " "
|
|
|
|
|
2019-12-21 09:16:41 +01:00
|
|
|
indent :: (Integral a) => a -> Lazy.Text
|
2020-03-29 15:56:07 +02:00
|
|
|
indent indentation = Lazy.Text.replicate (fromIntegral indentation) indentSymbol
|
2019-12-21 09:16:41 +01:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
selection :: Formatter -> Selection -> Lazy.Text
|
2019-12-21 09:16:41 +01:00
|
|
|
selection formatter = Lazy.Text.append indent' . encodeSelection
|
2019-08-03 23:57:27 +02:00
|
|
|
where
|
2020-09-09 17:04:31 +02:00
|
|
|
encodeSelection (FieldSelection fieldSelection) =
|
|
|
|
field incrementIndent fieldSelection
|
2020-09-07 22:01:49 +02:00
|
|
|
encodeSelection (InlineFragmentSelection fragmentSelection) =
|
|
|
|
inlineFragment incrementIndent fragmentSelection
|
|
|
|
encodeSelection (FragmentSpreadSelection fragmentSelection) =
|
|
|
|
fragmentSpread incrementIndent fragmentSelection
|
2019-08-03 23:57:27 +02:00
|
|
|
incrementIndent
|
2019-12-21 09:16:41 +01:00
|
|
|
| Pretty indentation <- formatter = Pretty $ indentation + 1
|
2019-08-03 23:57:27 +02:00
|
|
|
| otherwise = Minified
|
2019-12-21 09:16:41 +01:00
|
|
|
indent'
|
|
|
|
| Pretty indentation <- formatter = indent $ indentation + 1
|
|
|
|
| otherwise = ""
|
|
|
|
|
|
|
|
colon :: Formatter -> Lazy.Text
|
|
|
|
colon formatter = eitherFormat formatter ": " ":"
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-09-09 17:04:31 +02:00
|
|
|
-- | Converts Field into a string.
|
|
|
|
field :: Formatter -> Field -> Lazy.Text
|
|
|
|
field formatter (Field alias name args dirs set _)
|
2019-12-21 09:16:41 +01:00
|
|
|
= optempty prependAlias (fold alias)
|
2019-12-20 07:58:09 +01:00
|
|
|
<> Lazy.Text.fromStrict name
|
2019-08-02 13:52:51 +02:00
|
|
|
<> optempty (arguments formatter) args
|
|
|
|
<> optempty (directives formatter) dirs
|
2019-12-21 09:16:41 +01:00
|
|
|
<> optempty selectionSetOpt' set
|
2019-08-02 13:52:51 +02:00
|
|
|
where
|
2019-12-21 09:16:41 +01:00
|
|
|
prependAlias aliasName = Lazy.Text.fromStrict aliasName <> colon formatter
|
|
|
|
selectionSetOpt' = (eitherFormat formatter " " "" <>)
|
|
|
|
. selectionSetOpt formatter
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
arguments :: Formatter -> [Argument] -> Lazy.Text
|
2019-08-02 13:52:51 +02:00
|
|
|
arguments formatter = parensCommas formatter $ argument formatter
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
argument :: Formatter -> Argument -> Lazy.Text
|
2020-09-14 07:49:33 +02:00
|
|
|
argument formatter (Argument name value' _)
|
2019-12-20 07:58:09 +01:00
|
|
|
= Lazy.Text.fromStrict name
|
2019-12-21 09:16:41 +01:00
|
|
|
<> colon formatter
|
|
|
|
<> value formatter value'
|
2015-09-21 18:26:22 +02:00
|
|
|
|
|
|
|
-- * Fragments
|
|
|
|
|
2020-09-07 22:01:49 +02:00
|
|
|
fragmentSpread :: Formatter -> FragmentSpread -> Lazy.Text
|
|
|
|
fragmentSpread formatter (FragmentSpread name directives' _)
|
2019-12-25 06:45:29 +01:00
|
|
|
= "..." <> Lazy.Text.fromStrict name
|
|
|
|
<> optempty (directives formatter) directives'
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-09-07 22:01:49 +02:00
|
|
|
inlineFragment :: Formatter -> InlineFragment -> Lazy.Text
|
|
|
|
inlineFragment formatter (InlineFragment typeCondition directives' selections _)
|
|
|
|
= "... on "
|
|
|
|
<> Lazy.Text.fromStrict (fold typeCondition)
|
|
|
|
<> directives formatter directives'
|
2019-08-02 13:52:51 +02:00
|
|
|
<> eitherFormat formatter " " mempty
|
2020-09-07 22:01:49 +02:00
|
|
|
<> selectionSet formatter selections
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
fragmentDefinition :: Formatter -> FragmentDefinition -> Lazy.Text
|
2020-08-25 21:03:42 +02:00
|
|
|
fragmentDefinition formatter (FragmentDefinition name tc dirs sels _)
|
2019-12-20 07:58:09 +01:00
|
|
|
= "fragment " <> Lazy.Text.fromStrict name
|
|
|
|
<> " on " <> Lazy.Text.fromStrict tc
|
2019-08-02 13:52:51 +02:00
|
|
|
<> optempty (directives formatter) dirs
|
|
|
|
<> eitherFormat formatter " " mempty
|
|
|
|
<> selectionSet formatter sels
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2019-08-14 08:49:07 +02:00
|
|
|
-- * Miscellaneous
|
2019-08-13 07:24:05 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
-- | Converts a 'Directive' into a string.
|
|
|
|
directive :: Formatter -> Directive -> Lazy.Text
|
2020-09-18 07:32:58 +02:00
|
|
|
directive formatter (Directive name args _)
|
2019-12-20 07:58:09 +01:00
|
|
|
= "@" <> Lazy.Text.fromStrict name <> optempty (arguments formatter) args
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
directives :: Formatter -> [Directive] -> Lazy.Text
|
2019-08-14 08:49:07 +02:00
|
|
|
directives Minified = spaces (directive Minified)
|
2019-12-21 09:16:41 +01:00
|
|
|
directives formatter = Lazy.Text.cons ' ' . spaces (directive formatter)
|
2019-08-13 07:24:05 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
-- | Converts a 'Value' into a string.
|
|
|
|
value :: Formatter -> Value -> Lazy.Text
|
|
|
|
value _ (Variable x) = variable x
|
|
|
|
value _ (Int x) = Builder.toLazyText $ decimal x
|
|
|
|
value _ (Float x) = Builder.toLazyText $ realFloat x
|
|
|
|
value _ (Boolean x) = booleanValue x
|
|
|
|
value _ Null = "null"
|
|
|
|
value formatter (String string) = stringValue formatter string
|
|
|
|
value _ (Enum x) = Lazy.Text.fromStrict x
|
|
|
|
value formatter (List x) = listValue formatter x
|
|
|
|
value formatter (Object x) = objectValue formatter x
|
|
|
|
|
|
|
|
fromConstValue :: ConstValue -> Value
|
|
|
|
fromConstValue (ConstInt x) = Int x
|
|
|
|
fromConstValue (ConstFloat x) = Float x
|
|
|
|
fromConstValue (ConstBoolean x) = Boolean x
|
|
|
|
fromConstValue ConstNull = Null
|
|
|
|
fromConstValue (ConstString string) = String string
|
|
|
|
fromConstValue (ConstEnum x) = Enum x
|
|
|
|
fromConstValue (ConstList x) = List $ fromConstValue <$> x
|
|
|
|
fromConstValue (ConstObject x) = Object $ fromConstObjectField <$> x
|
|
|
|
where
|
|
|
|
fromConstObjectField (ObjectField key value') =
|
|
|
|
ObjectField key $ fromConstValue value'
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
booleanValue :: Bool -> Lazy.Text
|
2015-09-21 18:26:22 +02:00
|
|
|
booleanValue True = "true"
|
|
|
|
booleanValue False = "false"
|
|
|
|
|
2020-03-29 15:56:07 +02:00
|
|
|
quote :: Builder.Builder
|
|
|
|
quote = Builder.singleton '\"'
|
|
|
|
|
|
|
|
oneLine :: Text -> Builder
|
|
|
|
oneLine string = quote <> Text.foldr (mappend . escape) quote string
|
|
|
|
|
2019-12-21 09:16:41 +01:00
|
|
|
stringValue :: Formatter -> Text -> Lazy.Text
|
|
|
|
stringValue Minified string = Builder.toLazyText
|
2020-03-29 15:56:07 +02:00
|
|
|
$ quote <> Text.foldr (mappend . escape) quote string
|
|
|
|
stringValue (Pretty indentation) string =
|
|
|
|
if hasEscaped string
|
|
|
|
then stringValue Minified string
|
|
|
|
else Builder.toLazyText $ encoded lines'
|
|
|
|
where
|
|
|
|
isWhiteSpace char = char == ' ' || char == '\t'
|
|
|
|
isNewline char = char == '\n' || char == '\r'
|
|
|
|
hasEscaped = Text.any (not . isAllowed)
|
|
|
|
isAllowed char =
|
|
|
|
char == '\t' || isNewline char || (char >= '\x0020' && char /= '\x007F')
|
|
|
|
|
|
|
|
tripleQuote = Builder.fromText "\"\"\""
|
2020-07-08 08:16:14 +02:00
|
|
|
newline = Builder.singleton '\n'
|
2020-03-29 15:56:07 +02:00
|
|
|
|
|
|
|
strip = Text.dropWhile isWhiteSpace . Text.dropWhileEnd isWhiteSpace
|
|
|
|
lines' = map Builder.fromText $ Text.split isNewline (Text.replace "\r\n" "\n" $ strip string)
|
|
|
|
encoded [] = oneLine string
|
|
|
|
encoded [_] = oneLine string
|
2020-07-08 08:16:14 +02:00
|
|
|
encoded lines'' = tripleQuote <> newline
|
|
|
|
<> transformLines lines''
|
|
|
|
<> Builder.fromLazyText (indent indentation) <> tripleQuote
|
|
|
|
transformLines = foldr transformLine mempty
|
|
|
|
transformLine "" acc = newline <> acc
|
|
|
|
transformLine line' acc
|
|
|
|
= Builder.fromLazyText (indent (indentation + 1))
|
|
|
|
<> line' <> newline <> acc
|
2019-12-21 09:16:41 +01:00
|
|
|
|
|
|
|
escape :: Char -> Builder
|
|
|
|
escape char'
|
|
|
|
| char' == '\\' = Builder.fromString "\\\\"
|
|
|
|
| char' == '\"' = Builder.fromString "\\\""
|
|
|
|
| char' == '\b' = Builder.fromString "\\b"
|
|
|
|
| char' == '\f' = Builder.fromString "\\f"
|
2020-03-29 15:56:07 +02:00
|
|
|
| char' == '\n' = Builder.fromString "\\n"
|
2019-12-21 09:16:41 +01:00
|
|
|
| char' == '\r' = Builder.fromString "\\r"
|
2020-03-29 15:56:07 +02:00
|
|
|
| char' == '\t' = Builder.fromString "\\t"
|
2019-12-21 09:16:41 +01:00
|
|
|
| char' < '\x0010' = unicode "\\u000" char'
|
|
|
|
| char' < '\x0020' = unicode "\\u00" char'
|
|
|
|
| otherwise = Builder.singleton char'
|
|
|
|
where
|
|
|
|
unicode prefix = mappend (Builder.fromString prefix) . (hexadecimal . ord)
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
listValue :: Formatter -> [Value] -> Lazy.Text
|
2019-08-02 13:52:51 +02:00
|
|
|
listValue formatter = bracketsCommas formatter $ value formatter
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
objectValue :: Formatter -> [ObjectField Value] -> Lazy.Text
|
2019-08-03 23:57:27 +02:00
|
|
|
objectValue formatter = intercalate $ objectField formatter
|
|
|
|
where
|
|
|
|
intercalate f
|
|
|
|
= braces
|
2019-12-20 07:58:09 +01:00
|
|
|
. Lazy.Text.intercalate (eitherFormat formatter ", " ",")
|
2019-08-03 23:57:27 +02:00
|
|
|
. fmap f
|
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
objectField :: Formatter -> ObjectField Value -> Lazy.Text
|
|
|
|
objectField formatter (ObjectField name value') =
|
2019-12-21 09:16:41 +01:00
|
|
|
Lazy.Text.fromStrict name <> colon formatter <> value formatter value'
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
-- | Converts a 'Type' a type into a string.
|
|
|
|
type' :: Type -> Lazy.Text
|
|
|
|
type' (TypeNamed x) = Lazy.Text.fromStrict x
|
|
|
|
type' (TypeList x) = listType x
|
|
|
|
type' (TypeNonNull x) = nonNullType x
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
listType :: Type -> Lazy.Text
|
2019-08-13 07:24:05 +02:00
|
|
|
listType x = brackets (type' x)
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2020-05-22 10:11:48 +02:00
|
|
|
nonNullType :: NonNullType -> Lazy.Text
|
|
|
|
nonNullType (NonNullTypeNamed x) = Lazy.Text.fromStrict x <> "!"
|
|
|
|
nonNullType (NonNullTypeList x) = listType x <> "!"
|
2015-09-21 18:26:22 +02:00
|
|
|
|
|
|
|
-- * Internal
|
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
between :: Char -> Char -> Lazy.Text -> Lazy.Text
|
|
|
|
between open close = Lazy.Text.cons open . (`Lazy.Text.snoc` close)
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
parens :: Lazy.Text -> Lazy.Text
|
2015-09-22 10:45:14 +02:00
|
|
|
parens = between '(' ')'
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
brackets :: Lazy.Text -> Lazy.Text
|
2015-09-22 10:45:14 +02:00
|
|
|
brackets = between '[' ']'
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
braces :: Lazy.Text -> Lazy.Text
|
2015-09-22 10:45:14 +02:00
|
|
|
braces = between '{' '}'
|
2015-09-21 18:26:22 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
spaces :: forall a. (a -> Lazy.Text) -> [a] -> Lazy.Text
|
|
|
|
spaces f = Lazy.Text.intercalate "\SP" . fmap f
|
2015-09-22 10:45:14 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
parensCommas :: forall a. Formatter -> (a -> Lazy.Text) -> [a] -> Lazy.Text
|
2019-08-02 13:52:51 +02:00
|
|
|
parensCommas formatter f
|
|
|
|
= parens
|
2019-12-20 07:58:09 +01:00
|
|
|
. Lazy.Text.intercalate (eitherFormat formatter ", " ",")
|
2019-08-02 13:52:51 +02:00
|
|
|
. fmap f
|
2015-09-22 10:45:14 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
bracketsCommas :: Formatter -> (a -> Lazy.Text) -> [a] -> Lazy.Text
|
2019-08-02 13:52:51 +02:00
|
|
|
bracketsCommas formatter f
|
|
|
|
= brackets
|
2019-12-20 07:58:09 +01:00
|
|
|
. Lazy.Text.intercalate (eitherFormat formatter ", " ",")
|
2019-08-02 13:52:51 +02:00
|
|
|
. fmap f
|
2015-09-22 10:45:14 +02:00
|
|
|
|
2019-12-20 07:58:09 +01:00
|
|
|
bracesList :: forall a. Formatter -> (a -> Lazy.Text) -> [a] -> Lazy.Text
|
2019-08-03 23:57:27 +02:00
|
|
|
bracesList (Pretty intendation) f xs
|
2019-12-20 07:58:09 +01:00
|
|
|
= Lazy.Text.snoc (Lazy.Text.intercalate "\n" content) '\n'
|
|
|
|
<> (Lazy.Text.snoc $ Lazy.Text.replicate (fromIntegral intendation) " ") '}'
|
2019-08-03 23:57:27 +02:00
|
|
|
where
|
|
|
|
content = "{" : fmap f xs
|
2019-12-20 07:58:09 +01:00
|
|
|
bracesList Minified f xs = braces $ Lazy.Text.intercalate "," $ fmap f xs
|
2019-07-31 05:40:17 +02:00
|
|
|
|
2015-09-21 18:26:22 +02:00
|
|
|
optempty :: (Eq a, Monoid a, Monoid b) => (a -> b) -> a -> b
|
|
|
|
optempty f xs = if xs == mempty then mempty else f xs
|
2019-08-02 13:52:51 +02:00
|
|
|
|
|
|
|
eitherFormat :: forall a. Formatter -> a -> a -> a
|
2019-08-03 23:57:27 +02:00
|
|
|
eitherFormat (Pretty _) x _ = x
|
|
|
|
eitherFormat Minified _ x = x
|