Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.
/ mkjson Public archive

Commit 778d6cf

Browse files
committed
Support E notation in --num argument
1 parent 1658240 commit 778d6cf

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

src/Cli.hs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{-# LANGUAGE TupleSections #-}
22
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE TypeApplications #-}
34

45
module Cli
56
( Args(..)
@@ -13,7 +14,9 @@ import Data.Bifunctor (bimap)
1314
import qualified Data.Text as T
1415
import qualified Expr as E
1516
import Options.Applicative hiding (Const)
16-
import Text.Read (readMaybe)
17+
import qualified Text.Parsec as P
18+
import qualified Text.Parsec.String as P
19+
import Data.Functor (($>))
1720

1821

1922
type Field = (T.Text, E.Expr)
@@ -31,13 +34,32 @@ data Amount = Const Int
3134
deriving (Show)
3235

3336

34-
parseNum :: ReadM Amount
35-
parseNum = eitherReader parseNum'
37+
mapLeft :: (a -> c) -> Either a b -> Either c b
38+
mapLeft f = either (Left . f) Right
39+
40+
41+
-- >>> P.parse numParser "<num>" "Inf"
42+
-- Right Infinite
43+
--
44+
-- >>> P.parse numParser "<num>" "200"
45+
-- Right (Const 200)
46+
--
47+
-- >>> P.parse numParser "<num>" "5e4"
48+
-- Right (Const 50000)
49+
numParser :: P.Parser Amount
50+
numParser = inf <|> integer
3651
where
37-
parseNum' "Inf" = Right Infinite
38-
parseNum' s = case readMaybe s of
39-
(Just n) -> Right (Const n)
40-
Nothing -> Left "Expected a number or `Inf` for infinite records"
52+
inf = P.string "Inf" $> Infinite
53+
integer = do
54+
digits <- read @Int <$> P.many1 P.digit
55+
power <- P.optionMaybe eNotation
56+
pure . Const $ digits * maybe 1 (10 ^) power
57+
eNotation :: P.Parser Int
58+
eNotation = read @Int <$> (P.oneOf "eE" >> P.many1 P.digit)
59+
60+
61+
parseNum :: ReadM Amount
62+
parseNum = eitherReader $ \s -> mapLeft show $ P.parse numParser s s
4163

4264

4365
parseExpr :: String -> Either String Field
@@ -52,7 +74,7 @@ parseExpr s =
5274

5375
args :: Parser Args
5476
args = Args
55-
<$> optional
77+
<$> optional
5678
( option auto
5779
( long "seed"
5880
<> help "A seed for the random data generator"
@@ -62,12 +84,11 @@ args = Args
6284
<> value (Const 1)
6385
<> help "Number of records to generate. Use `Inf` for infinite records" )
6486
<*> many (argument (eitherReader parseExpr) (metavar "FIELDS..."))
65-
6687

6788

6889
parseArgs :: [String] -> IO Args
6990
parseArgs cliArgs = handleParseResult $ execParserPure defaultPrefs opts cliArgs
7091
where
7192
opts = info (args <**> helper)
72-
( fullDesc <> progDesc
93+
( fullDesc <> progDesc
7394
"Generate random JSON records. Use <field>=<provider> pairs to specify the fields the records should have." )

0 commit comments

Comments
 (0)