aboutsummaryrefslogtreecommitdiffstats
path: root/cli/app/Main.hs
blob: 6006e7c6937b32aeb4490de0cc84223d8b36ce4a (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
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NoFieldSelectors #-}

module Main where

import API.Collection qualified
import Control.Applicative ((<**>))
import Data.Aeson qualified as J
import Data.ByteString.Lazy qualified as LB
import Data.Text qualified as T
import Options.Applicative qualified as O
import Text.ParserCombinators.ReadP qualified as R
import Text.ParserCombinators.ReadPrec qualified as R
import Text.Read (Read (..))

data Args = Args
  { cmd :: Cmd
  }

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

data Cmd = Collection CollectionCmd

cmd_ :: O.Parser Cmd
cmd_ =
  O.hsubparser . mconcat $
    [ O.command "collection" . O.info collectionCmd $
        O.progDesc "Manage content collections"
    ]

data CollectionCmd = CollectionInsert
  { filePath :: CollectionPath
  }

data CollectionPath = CollectionPath
  { collectionName :: T.Text,
    fileName :: T.Text
  }

instance Read CollectionPath where
  readPrec = R.lift do
    (T.pack -> collectionName) <- R.munch (/= '/')
    _ <- R.string "/"
    (T.pack -> fileName) <- do
      fileName <- R.munch (liftA2 (&&) (/= '.') (/= '/'))
      fileExt <- R.string ".json"
      pure (fileName <> fileExt)
    pure CollectionPath {..}

instance Show CollectionPath where
  show (CollectionPath {collectionName, fileName}) =
    show (collectionName <> "/" <> fileName)

collectionCmd :: O.Parser Cmd
collectionCmd =
  fmap Collection . O.hsubparser . mconcat $
    [ O.command "insert" . O.info collectionInsertCmd $
        O.progDesc "Insert an entity"
    ]

collectionInsertCmd :: O.Parser CollectionCmd
collectionInsertCmd =
  CollectionInsert
    <$> collectionPathArg

collectionPathArg :: O.Parser CollectionPath
collectionPathArg =
  O.argument O.auto (O.metavar "COLLECTION_PATH")

main :: IO ()
main = do
  O.execParser (O.info (args <**> O.helper) O.idm) >>= \case
    Args
      { cmd =
          Collection
            CollectionInsert
              { filePath = CollectionPath {collectionName, fileName}
              }
      } ->
        print
          =<< API.Collection.insert collectionName fileName
          =<< J.throwDecode
          =<< LB.getContents