From 5175586def05410890023ab340b8381045de6811 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 26 Aug 2019 10:14:46 +0200 Subject: [PATCH] Provide more documentation on functions and types --- CHANGELOG.md | 4 ++ README.md | 4 +- src/Language/GraphQL/AST/Core.hs | 86 ++++++++++++++++++++++++++------ src/Language/GraphQL/Lexer.hs | 2 + src/Language/GraphQL/Parser.hs | 1 + src/Language/GraphQL/Trans.hs | 1 + stack.yaml | 2 +- 7 files changed, 81 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efdf1c6..060ccab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Change Log All notable changes to this project will be documented in this file. +## [Unreleased] +### Added +- Minimal documentation for all public symbols. + ## [0.5.0.0] - 2019-08-14 ### Added - `executeWithName` executes an operation with the given name. diff --git a/README.md b/README.md index da7aa7b..136b9dd 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ GraphQL implementation in Haskell. This implementation is relatively low-level by design, it doesn't provide any mappings between the GraphQL types and Haskell's type system and avoids -compile-time magic. It focuses on flexibility instead instead, so other -solutions can be built on top of it. +compile-time magic. It focuses on flexibility instead, so other solutions can +be built on top of it. ## State of the work diff --git a/src/Language/GraphQL/AST/Core.hs b/src/Language/GraphQL/AST/Core.hs index 87dced9..977153f 100644 --- a/src/Language/GraphQL/AST/Core.hs +++ b/src/Language/GraphQL/AST/Core.hs @@ -19,30 +19,84 @@ import Data.Text (Text) -- | Name type Name = Text +-- | GraphQL document is a non-empty list of operations. type Document = NonEmpty Operation -data Operation = Query (Maybe Text) (NonEmpty Field) - | Mutation (Maybe Text) (NonEmpty Field) - deriving (Eq,Show) +-- | GraphQL has 3 operation types: queries, mutations and subscribtions. +-- +-- Currently only queries and mutations are supported. +data Operation + = Query (Maybe Text) (NonEmpty Field) + | Mutation (Maybe Text) (NonEmpty Field) + deriving (Eq, Show) -data Field = Field (Maybe Alias) Name [Argument] [Field] deriving (Eq,Show) +-- | A single GraphQL field. +-- +-- Only required property of a field, is its name. Optionally it can also have +-- an alias, arguments or a list of subfields. +-- +-- Given the following query: +-- +-- @ +-- { +-- zuck: user(id: 4) { +-- id +-- name +-- } +-- } +-- @ +-- +-- * "user", "id" and "name" are field names. +-- * "user" has two subfields, "id" and "name". +-- * "zuck" is an alias for "user". "id" and "name" have no aliases. +-- * "id: 4" is an argument for "name". "id" and "name don't have any +-- arguments. +data Field = Field (Maybe Alias) Name [Argument] [Field] deriving (Eq, Show) +-- | Alternative field name. +-- +-- @ +-- { +-- smallPic: profilePic(size: 64) +-- bigPic: profilePic(size: 1024) +-- } +-- @ +-- +-- Here "smallPic" and "bigPic" are aliases for the same field, "profilePic", +-- used to distinquish between profile pictures with different arguments +-- (sizes). type Alias = Name -data Argument = Argument Name Value deriving (Eq,Show) +-- | Single argument. +-- +-- @ +-- { +-- user(id: 4) { +-- name +-- } +-- } +-- @ +-- +-- Here "id" is an argument for the field "user" and its value is 4. +data Argument = Argument Name Value deriving (Eq, Show) -data Value = ValueInt Int32 - -- GraphQL Float is double precision - | ValueFloat Double - | ValueString Text - | ValueBoolean Bool - | ValueNull - | ValueEnum Name - | ValueList [Value] - | ValueObject [ObjectField] - deriving (Eq,Show) +-- | Represents accordingly typed GraphQL values. +data Value + = ValueInt Int32 + -- GraphQL Float is double precision + | ValueFloat Double + | ValueString Text + | ValueBoolean Bool + | ValueNull + | ValueEnum Name + | ValueList [Value] + | ValueObject [ObjectField] + deriving (Eq, Show) instance IsString Value where fromString = ValueString . fromString -data ObjectField = ObjectField Name Value deriving (Eq,Show) +-- | Key-value pair. +-- +-- A list of 'ObjectField's represents a GraphQL object type. +data ObjectField = ObjectField Name Value deriving (Eq, Show) diff --git a/src/Language/GraphQL/Lexer.hs b/src/Language/GraphQL/Lexer.hs index 8ca03bf..dc000b5 100644 --- a/src/Language/GraphQL/Lexer.hs +++ b/src/Language/GraphQL/Lexer.hs @@ -71,6 +71,8 @@ type Parser = Parsec Void T.Text ignoredCharacters :: Parser () ignoredCharacters = space1 <|> skipSome (char ',') +-- | Parser that skips comments and meaningless characters, whitespaces and +-- commas. spaceConsumer :: Parser () spaceConsumer = Lexer.space ignoredCharacters comment empty diff --git a/src/Language/GraphQL/Parser.hs b/src/Language/GraphQL/Parser.hs index dac15c2..4bc17b9 100644 --- a/src/Language/GraphQL/Parser.hs +++ b/src/Language/GraphQL/Parser.hs @@ -16,6 +16,7 @@ import Text.Megaparsec ( lookAhead , () ) +-- | Parser for the GraphQL documents. document :: Parser Document document = unicodeBOM >> spaceConsumer >> lexeme (manyNE definition) diff --git a/src/Language/GraphQL/Trans.hs b/src/Language/GraphQL/Trans.hs index 5ca72e9..d92aea7 100644 --- a/src/Language/GraphQL/Trans.hs +++ b/src/Language/GraphQL/Trans.hs @@ -9,6 +9,7 @@ import Control.Monad.Trans.Class (MonadTrans(..)) import Control.Monad.Trans.Except (ExceptT) import Data.Text (Text) +-- | Monad transformer stack used by the resolvers to provide error handling. newtype ActionT m a = ActionT { runActionT :: ExceptT Text m a } instance Functor m => Functor (ActionT m) where diff --git a/stack.yaml b/stack.yaml index efa93aa..84a066f 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,4 +1,4 @@ -resolver: lts-14.0 +resolver: lts-14.2 packages: - '.' extra-deps: []