diff options
| -rw-r--r-- | client/src/Thermoprint/Client.hs | 52 | ||||
| -rw-r--r-- | client/thermoprint-client.cabal | 2 | ||||
| -rw-r--r-- | client/thermoprint-client.nix | 9 |
3 files changed, 41 insertions, 22 deletions
diff --git a/client/src/Thermoprint/Client.hs b/client/src/Thermoprint/Client.hs index 2b99e7e..758a256 100644 --- a/client/src/Thermoprint/Client.hs +++ b/client/src/Thermoprint/Client.hs | |||
| @@ -6,7 +6,8 @@ | |||
| 6 | -- | A client library for 'Thermoprint.API' | 6 | -- | A client library for 'Thermoprint.API' |
| 7 | module Thermoprint.Client | 7 | module Thermoprint.Client |
| 8 | ( Client(..) | 8 | ( Client(..) |
| 9 | , mkClient | 9 | , mkClient, mkClient' |
| 10 | , throwNat, ioNat | ||
| 10 | -- = Reexports | 11 | -- = Reexports |
| 11 | , ServantError(..) | 12 | , ServantError(..) |
| 12 | , module Servant.Common.BaseUrl | 13 | , module Servant.Common.BaseUrl |
| @@ -26,53 +27,58 @@ import Servant.API | |||
| 26 | import Servant.Server.Internal.Enter | 27 | import Servant.Server.Internal.Enter |
| 27 | import Control.Monad.Trans.Either | 28 | import Control.Monad.Trans.Either |
| 28 | 29 | ||
| 30 | import Control.Monad.Catch (Exception, MonadThrow(..)) | ||
| 31 | import Control.Monad.IO.Class (MonadIO(..)) | ||
| 32 | |||
| 33 | import Control.Monad | ||
| 29 | import Control.Category | 34 | import Control.Category |
| 30 | import Prelude hiding (id, (.)) | 35 | import Prelude hiding (id, (.)) |
| 31 | 36 | ||
| 37 | instance Exception ServantError | ||
| 38 | |||
| 32 | -- | All 'ThermoprintAPI'-functions as a record | 39 | -- | All 'ThermoprintAPI'-functions as a record |
| 33 | -- | 40 | -- |
| 34 | -- Use like this: | 41 | -- Use like this: |
| 35 | -- | 42 | -- |
| 36 | -- > import Control.Category | 43 | -- > import Control.Category |
| 37 | -- > import Prelude hiding (id, (.)) | 44 | -- > import Prelude hiding (id, (.)) |
| 38 | -- > import Data.Either | ||
| 39 | -- > | 45 | -- > |
| 40 | -- > main :: IO () | 46 | -- > main :: IO () |
| 41 | -- > -- ^ Display a list of printers with their status | 47 | -- > -- ^ Display a list of printers with their status |
| 42 | -- > main = either print print =<< runEitherT printers | 48 | -- > main = print =<< printers |
| 43 | -- > where Client{..} = mkClient id $ Http "localhost" 3000 | 49 | -- > where Client{..} = mkClient' $ Http "localhost" 3000 |
| 44 | data Client m = Client | 50 | data Client m = Client |
| 45 | { printers :: EitherT ServantError m (Map PrinterId PrinterStatus) | 51 | { printers :: m (Map PrinterId PrinterStatus) |
| 46 | -- ^ List all printers | 52 | -- ^ List all printers |
| 47 | , jobs :: Maybe PrinterId | 53 | , jobs :: Maybe PrinterId |
| 48 | -> Maybe (Range (JobId)) | 54 | -> Maybe (Range (JobId)) |
| 49 | -> Maybe (Range (UTCTime)) | 55 | -> Maybe (Range (UTCTime)) |
| 50 | -> EitherT ServantError m (Seq (JobId, UTCTime, JobStatus)) | 56 | -> m (Seq (JobId, UTCTime, JobStatus)) |
| 51 | -- ^ @jobs p minId maxId minTime maxTime@ lists a selection of jobs | 57 | -- ^ @jobs p minId maxId minTime maxTime@ lists a selection of jobs |
| 52 | , jobCreate :: Maybe PrinterId -> Printout -> EitherT ServantError m JobId | 58 | , jobCreate :: Maybe PrinterId -> Printout -> m JobId |
| 53 | -- ^ Send a 'Printout' to be queued | 59 | -- ^ Send a 'Printout' to be queued |
| 54 | , job :: JobId -> EitherT ServantError m Printout | 60 | , job :: JobId -> m Printout |
| 55 | -- ^ Retrieve the contents of a job | 61 | -- ^ Retrieve the contents of a job |
| 56 | , jobStatus :: JobId -> EitherT ServantError m JobStatus | 62 | , jobStatus :: JobId -> m JobStatus |
| 57 | -- ^ Query a jobs status | 63 | -- ^ Query a jobs status |
| 58 | , jobDelete :: JobId -> EitherT ServantError m () | 64 | , jobDelete :: JobId -> m () |
| 59 | -- ^ Delete a job from the queue (not from history or while it is being printed) | 65 | -- ^ Delete a job from the queue (not from history or while it is being printed) |
| 60 | , drafts :: EitherT ServantError m (Map DraftId (Maybe DraftTitle)) | 66 | , drafts :: m (Map DraftId (Maybe DraftTitle)) |
| 61 | -- ^ List all saved drafts | 67 | -- ^ List all saved drafts |
| 62 | , draftCreate :: Maybe DraftTitle | 68 | , draftCreate :: Maybe DraftTitle |
| 63 | -> Printout | 69 | -> Printout |
| 64 | -> EitherT ServantError m DraftId | 70 | -> m DraftId |
| 65 | -- ^ Create a new draft | 71 | -- ^ Create a new draft |
| 66 | , draftReplace :: DraftId | 72 | , draftReplace :: DraftId |
| 67 | -> Maybe DraftTitle | 73 | -> Maybe DraftTitle |
| 68 | -> Printout | 74 | -> Printout |
| 69 | -> EitherT ServantError m () | 75 | -> m () |
| 70 | -- ^ Replace the contents and title of an existing draft | 76 | -- ^ Replace the contents and title of an existing draft |
| 71 | , draft :: DraftId -> EitherT ServantError m (Maybe DraftTitle, Printout) | 77 | , draft :: DraftId -> m (Maybe DraftTitle, Printout) |
| 72 | -- ^ Retrieve the contents and title of a draft | 78 | -- ^ Retrieve the contents and title of a draft |
| 73 | , draftDelete :: DraftId -> EitherT ServantError m () | 79 | , draftDelete :: DraftId -> m () |
| 74 | -- ^ Delete a draft | 80 | -- ^ Delete a draft |
| 75 | , draftPrint :: DraftId -> Maybe PrinterId -> EitherT ServantError m JobId | 81 | , draftPrint :: DraftId -> Maybe PrinterId -> m JobId |
| 76 | -- ^ Send a draft to be printed | 82 | -- ^ Send a draft to be printed |
| 77 | } | 83 | } |
| 78 | 84 | ||
| @@ -80,7 +86,7 @@ withArgs :: (x -> a :<|> b) -> ((x -> a) :<|> (x -> b)) | |||
| 80 | -- ^ Undo factoring of APIs | 86 | -- ^ Undo factoring of APIs |
| 81 | withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI | 87 | withArgs subAPI = (\(a :<|> _) -> a) . subAPI :<|> (\(_ :<|> b) -> b) . subAPI |
| 82 | 88 | ||
| 83 | mkClient :: (IO :~> m) -- ^ A monad functor ('Nat') used to make the api functions work in any monad which can be constructed from 'IO' | 89 | mkClient :: (EitherT ServantError IO :~> m) -- ^ A monad functor ('Nat') used to make the api functions work in any monad which can do 'IO' and handle errors |
| 84 | -> BaseUrl | 90 | -> BaseUrl |
| 85 | -> Client m | 91 | -> Client m |
| 86 | -- ^ Generate a 'Client' | 92 | -- ^ Generate a 'Client' |
| @@ -91,4 +97,14 @@ mkClient n url = Client{..} | |||
| 91 | :<|> (withArgs -> job :<|> (withArgs -> jobStatus :<|> jobDelete)) | 97 | :<|> (withArgs -> job :<|> (withArgs -> jobStatus :<|> jobDelete)) |
| 92 | :<|> (drafts :<|> draftCreate) | 98 | :<|> (drafts :<|> draftCreate) |
| 93 | :<|> (withArgs -> draftReplace :<|> (withArgs -> draft :<|> (withArgs -> draftDelete :<|> draftPrint))) | 99 | :<|> (withArgs -> draftReplace :<|> (withArgs -> draft :<|> (withArgs -> draftDelete :<|> draftPrint))) |
| 94 | = enter (hoistNat n) $ client thermoprintAPI url | 100 | = enter n $ client thermoprintAPI url |
| 101 | |||
| 102 | mkClient' :: (MonadThrow m, MonadIO m) => BaseUrl -> Client m | ||
| 103 | -- ^ @mkClient' = mkClient $ ioNat . throwNat@ | ||
| 104 | mkClient' = mkClient $ ioNat . throwNat | ||
| 105 | |||
| 106 | throwNat :: (Exception e, MonadThrow m) => EitherT e m :~> m | ||
| 107 | throwNat = Nat $ either throwM return <=< runEitherT | ||
| 108 | |||
| 109 | ioNat :: MonadIO m => IO :~> m | ||
| 110 | ioNat = Nat liftIO | ||
diff --git a/client/thermoprint-client.cabal b/client/thermoprint-client.cabal index 39e2622..69091fd 100644 --- a/client/thermoprint-client.cabal +++ b/client/thermoprint-client.cabal | |||
| @@ -28,5 +28,7 @@ library | |||
| 28 | , containers >=0.5.6 && <1 | 28 | , containers >=0.5.6 && <1 |
| 29 | , either >=4.4.1 && <5 | 29 | , either >=4.4.1 && <5 |
| 30 | , time >=1.5.0 && <2 | 30 | , time >=1.5.0 && <2 |
| 31 | , exceptions >=0.8.2 && <1 | ||
| 32 | , transformers >=0.4.2 && <1 | ||
| 31 | hs-source-dirs: src | 33 | hs-source-dirs: src |
| 32 | default-language: Haskell2010 | 34 | default-language: Haskell2010 |
diff --git a/client/thermoprint-client.nix b/client/thermoprint-client.nix index e424403..6471b06 100644 --- a/client/thermoprint-client.nix +++ b/client/thermoprint-client.nix | |||
| @@ -1,13 +1,14 @@ | |||
| 1 | { mkDerivation, base, containers, either, servant, servant-client | 1 | { mkDerivation, base, containers, either, exceptions, servant |
| 2 | , servant-server, stdenv, thermoprint-spec | 2 | , servant-client, servant-server, stdenv, thermoprint-spec, time |
| 3 | , transformers | ||
| 3 | }: | 4 | }: |
| 4 | mkDerivation { | 5 | mkDerivation { |
| 5 | pname = "thermoprint-client"; | 6 | pname = "thermoprint-client"; |
| 6 | version = "0.0.0"; | 7 | version = "0.0.0"; |
| 7 | src = ./.; | 8 | src = ./.; |
| 8 | libraryHaskellDepends = [ | 9 | libraryHaskellDepends = [ |
| 9 | base containers either servant servant-client servant-server | 10 | base containers either exceptions servant servant-client |
| 10 | thermoprint-spec | 11 | servant-server thermoprint-spec time transformers |
| 11 | ]; | 12 | ]; |
| 12 | homepage = "http://dirty-haskell.org/tags/thermoprint.html"; | 13 | homepage = "http://dirty-haskell.org/tags/thermoprint.html"; |
| 13 | description = "Client for thermoprint-spec"; | 14 | description = "Client for thermoprint-spec"; |
