aboutsummaryrefslogtreecommitdiffstats
path: root/acms/app/Main.hs
blob: 3dd339c0127c20adb011154d7de326790276820b (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
module Main where

import ACMS.ACMS qualified
import ACMS.API.Query qualified
import ACMS.API.REST.Collection qualified
import Collection
import Control.Applicative ((<**>))
import Data.Aeson qualified as J
import Data.Aeson.Encode.Pretty qualified as J
import Data.ByteString.Lazy.Char8 qualified as LB
import Data.ByteString.Lazy.UTF8 qualified as LB
import Data.Text qualified as T
import Options.Applicative qualified as O

newtype Args = Args
  { cmd :: Cmd
  }

args :: O.Parser Args
args = Args <$> cmd_

data Cmd
  = CollectionCmd CollectionCmd
  | QueryCmd
  | ServeCmd ServeOpts

cmd_ :: O.Parser Cmd
cmd_ =
  O.hsubparser . mconcat $
    [ O.command "collection" . O.info collectionCmd $
        O.progDesc "Manage content collections",
      O.command "query" . O.info queryCmd $
        O.progDesc "Manage content through queries",
      O.command "serve" . O.info serveCmd $
        O.progDesc "Serve content repository"
    ]

data CollectionCmd
  = CollectionAdd Collection
  | CollectionView CollectionItem
  | CollectionEdit CollectionItem
  | CollectionDelete CollectionItem
  | --
    CollectionList Collection
  | CollectionSchema Collection

collectionCmd :: O.Parser Cmd
collectionCmd = do
  fmap CollectionCmd . O.hsubparser . mconcat $
    [ O.command "add" . O.info (CollectionAdd <$> collectionArg) $
        O.progDesc "Add an entity",
      O.command "view" . O.info (CollectionView <$> collectionItemArg) $
        O.progDesc "View an entity",
      O.command "edit" . O.info (CollectionEdit <$> collectionItemArg) $
        O.progDesc "Edit an entity",
      O.command "delete" . O.info (CollectionDelete <$> collectionItemArg) $
        O.progDesc "Delete an entity",
      --
      O.command "list" . O.info (CollectionList <$> collectionArg) $
        O.progDesc "List entities",
      O.command "schema" . O.info (CollectionSchema <$> collectionArg) $
        O.progDesc "Show the collection's schema"
    ]

collectionItemArg :: O.Parser CollectionItem
collectionItemArg =
  O.argument O.auto (O.metavar "COLLECTION_PATH")

collectionArg :: O.Parser Collection
collectionArg =
  Collection . T.pack <$> O.strArgument (O.metavar "COLLECTION_NAME")

queryCmd :: O.Parser Cmd
queryCmd = pure QueryCmd

data ServeOpts = ServeOpts
  { serverPort :: Int,
    contentRepositoryPath :: FilePath
  }

serveCmd :: O.Parser Cmd
serveCmd =
  ServeCmd
    <$> ( ServeOpts
            <$> O.option
              O.auto
              ( O.metavar "PORT"
                  <> O.showDefault
                  <> O.value 8081
                  <> O.long "port"
                  <> O.short 'p'
                  <> O.help "The server port"
              )
            <*> O.strArgument
              ( O.metavar "PATH"
                  <> O.help "Path to the content repository"
              )
        )

main :: IO ()
main =
  O.execParser (O.info (args <**> O.helper) O.idm) >>= \case
    Args {cmd = CollectionCmd cmd} -> case cmd of
      CollectionAdd collection ->
        LB.putStr . J.encodePretty
          =<< ACMS.API.REST.Collection.create collection
          =<< J.throwDecode
          =<< LB.getContents
      CollectionView collectionItem ->
        LB.putStr . J.encodePretty
          =<< ACMS.API.REST.Collection.read collectionItem
      CollectionDelete collectionItem ->
        LB.putStr . J.encodePretty
          =<< ACMS.API.REST.Collection.delete collectionItem
      CollectionEdit collectionItem ->
        LB.putStr . J.encodePretty
          =<< ACMS.API.REST.Collection.update collectionItem
          =<< J.throwDecode
          =<< LB.getContents
      CollectionList collection ->
        mapM_ (LB.putStrLn . J.encodePretty)
          =<< ACMS.API.REST.Collection.list collection
      CollectionSchema collection ->
        LB.putStr . J.encodePretty @J.Value
          =<< ACMS.API.REST.Collection.schema collection
    Args {cmd = QueryCmd} ->
      LB.putStr . J.encodePretty @J.Value
        =<< ACMS.API.Query.query . LB.toString
        =<< LB.getContents
    Args {cmd = ServeCmd (ServeOpts {serverPort, contentRepositoryPath})} ->
      ACMS.ACMS.run ACMS.ACMS.Config {serverPort, contentRepositoryPath}