From 81b29fec71903f5b03b730a9416bb48edb48e73d Mon Sep 17 00:00:00 2001 From: Paul Brinkmeier Date: Thu, 25 Aug 2022 19:39:05 +0200 Subject: [PATCH] Add createOrder function --- src/Lisa/Squeak.hs | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/Lisa/Squeak.hs b/src/Lisa/Squeak.hs index 65c24d1..869d688 100644 --- a/src/Lisa/Squeak.hs +++ b/src/Lisa/Squeak.hs @@ -2,6 +2,7 @@ module Lisa.Squeak where +import Control.Applicative ((<|>)) import Data.Aeson (FromJSON(parseJSON), ToJSON(toJSON), Value, (.:), (.:?), (.=), object, withObject) import Data.Text (Text) import Data.Time.Calendar (Day) @@ -159,3 +160,60 @@ login username password = fmap unLoginResult <$> replyToEither <$> responseBody [ "username" .= username , "password" .= password ] + +data SqueakError + = SqueakError + Text -- ^ Error code + Text -- ^ Human-readable message + | GQLErrors [GQLError] + deriving (Show) + +instance FromJSON SqueakError where + parseJSON = withObject "SqueakError" $ \v -> SqueakError + <$> v .: "errorCode" + <*> v .: "msg" + +newtype SqueakErrorOr a = SqueakErrorOr (Either SqueakError a) + deriving (Show) + +instance FromJSON a => FromJSON (SqueakErrorOr a) where + -- | Parse 'SqueakError' if @errorCode@ and @msg@ are present; otherwise, parse an 'a'. + parseJSON v = SqueakErrorOr + <$> ((Left <$> parseJSON v) + <|> (Right <$> parseJSON v)) + +data CreateOrderResult = CreateOrderResult { unCreateOrderResult :: SqueakErrorOr Order } + deriving (Show) + +instance (FromJSON CreateOrderResult) where + parseJSON = withObject "CreateOrderResult" $ \v -> CreateOrderResult + <$> v .: "createOrder" + +data Order = Order + { orderId :: Text + , orderTag :: Text + , orderNumPages :: Int + } + deriving (Show) + +instance FromJSON Order where + parseJSON = withObject "Order" $ \v -> Order + <$> v .: "id" + <*> v .: "tag" + <*> v .: "numPages" + +joinErrors :: Either [GQLError] (SqueakErrorOr a) -> Either SqueakError a +joinErrors (Left errors) = Left $ GQLErrors errors +joinErrors (Right (SqueakErrorOr inner)) = inner + +createOrder :: Text -> [Text] -> Req (Either SqueakError Order) +createOrder tag documents = joinErrors <$> fmap unCreateOrderResult <$> replyToEither <$> responseBody <$> req POST serverUrl (ReqBodyJson $ GQLQueryWithVars q vars) jsonResponse mempty + where q = "mutation CreateOrder($tag: String!, $documents: [DocumentId!]!) \ + \ { createOrder(tag: $tag, documents: $documents) \ + \ { ... on Error { errorCode msg } \ + \ ... on Order { id tag numPages } \ + \ } }" + vars = object + [ "tag" .= tag + , "documents" .= documents + ]