{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_GHC -Wno-missing-signatures #-}
module API where
import Text.Read (readMaybe)
import qualified Pipes as P
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TL

import Symantic.HTTP

-- | Define the API, common to the client and server.
-- Either use @NoMonomorphismRestriction@ like here,
-- or add an argument to 'api',
-- to let the compiler infer its (complex) type.
-- Read the executables of the client and of the server
-- to see how to derive code from this 'api'.
api =
 "succ" </> capture @Integer "n"
        <.> get @Integer @'[PlainText]

  <!>
  "countdown" </> capture @Integer "n"
              <.> getStream @(P.Producer Integer IO ())
                            @'[PlainText]
                            @NewlineFraming

instance MimeEncodable Integer PlainText where
  mimeEncode _ = TL.encodeUtf8 . TL.pack . show
instance MimeDecodable Integer PlainText where
  mimeDecode _mt bs =
    let s = TL.unpack $ TL.decodeUtf8 bs in
    case readMaybe s of
     Nothing -> Left $ "cannot parse as Integer: "<>s
     Just n -> Right n