aboutsummaryrefslogtreecommitdiff
path: root/servant/src/Main.hs
blob: 9d885596dcc9cbde2cdfedbe651113f9b1b18d28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
{-# LANGUAGE RecordWildCards, OverloadedStrings #-}

import Thermoprint
import Thermoprint.Api

import Data.Aeson
import Network.Wai
import Network.Wai.Handler.Warp
import Servant
import qualified Data.Text.Lazy as Text
import qualified Data.ByteString.Lazy.Char8 as ByteString
import Data.ByteString.Lazy.Char8 (ByteString)
import GHC.Generics

import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Either

import Options.Applicative

import System.IO

server :: Options -> Integer -> Block String -> EitherT ServantErr IO ()
server Options{..} printerNo printOut = do
  printerPath <- case genericIndex printers printerNo of
    Just path -> return path
    Nothing -> left $ err404 { errBody = "printerId out of bounds" }
  liftIO $ withFile printerPath WriteMode doPrint
  where
    doPrint handle = do
      hSetBuffering handle NoBuffering
      ByteString.hPut handle $ render' printOut
    genericIndex :: Integral i => [a] -> i -> Maybe a
    genericIndex (x:_)  0 = Just x
    genericIndex (_:xs) n
      | n > 0     = genericIndex xs (n - 1)
      | otherwise = Nothing
    genericIndex _ _ = Nothing

data Options = Options
               { port :: Int
               , printers :: [FilePath]
               }

options :: Parser Options
options = Options
          <$> option auto (
            long "port"
            <> short 'p'
            <> metavar "PORT"
            <> help "The port we'll run the server on"
            <> value 8080
            <> showDefault
            )
          <*> some (strArgument (
                        metavar "PATH [...]"
                        <> help "Path to one of the printers to use"
                                ))

thermoprintApi :: Proxy ThermoprintApi
thermoprintApi = Proxy

main :: IO ()
main = do
  execParser opts >>= main'
  where
    opts = info (helper <*> options) (
      fullDesc
      <> header "thermoprint-servant - A REST server for interacting with a cheap thermoprinter"
                                     )
    main' args@(Options{..}) = run port $ serve thermoprintApi (server args)