Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
"tests"
],
"dependencies": {
"purescript-foreign": "^5.0.0",
"purescript-validation": "^4.0.0",
"purescript-record": "^2.0.0",
"purescript-node-process": "^7.0.0",
"purescript-console": "^4.1.0"
"purescript-foreign": "^6.0.1",
"purescript-validation": "^5.0.0",
"purescript-record": "^3.0.0",
"purescript-typelevel-prelude": "^6.0.0",
"purescript-node-process": "^8.2.0",
"purescript-console": "^5.0.0",
"purescript-numbers": "^8.0.0"
}
}
22 changes: 11 additions & 11 deletions src/Node/Commando.purs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ import Data.List (List(Nil), (:))
import Data.Maybe (Maybe(..))
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
import Node.Optlicative.Types (Optlicative)
import Record (delete, get)
import Prim.Row as R
import Prim.RowList as RL
import Type.Data.RowList (RLProxy(..))
import Record (delete, get)
import Type.Proxy (Proxy(..))

class RLCommando
(rl :: RL.RowList)
(row :: # Type)
(rl :: RL.RowList Type)
(row :: Row Type)
(a :: Type)
| rl -> row
where
rlCommando :: RLProxy rl -> Record row -> List String -> Maybe {cmd :: String, opt :: Optlicative a}
rlCommando :: Proxy rl -> Record row -> List String -> Maybe {cmd :: String, opt :: Optlicative a}

instance basisRlHelp :: RLCommando RL.Nil () a where
rlCommando _ _ _ = Nothing
Expand All @@ -46,13 +46,13 @@ instance ihRlHelp ::
in
if cmd == reflectSymbol sproxy
then Just {cmd, opt}
else rlCommando (RLProxy :: RLProxy tail) rectail args
else rlCommando (Proxy :: Proxy tail) rectail args

rlCommando _ rec args@(x : xs) = -- haven't found final command yet
let
sproxy = SProxy :: SProxy k
rldeeper = RLProxy :: RLProxy list'
rlwider = RLProxy :: RLProxy tail
rldeeper = Proxy :: Proxy list'
rlwider = Proxy :: Proxy tail
rec' = (getrow (get sproxy rec)) :: Record row'
rectail = (delete sproxy rec) :: Record rowtail
in
Expand All @@ -62,16 +62,16 @@ instance ihRlHelp ::

rlCommando _ _ _ = Nothing -- ran out of command path elements

class Commando (row :: # Type) a where
class Commando (row :: Row Type) a where
commando :: Record row -> List String -> Maybe {cmd :: String, opt :: Optlicative a}

instance rowHelpInst ::
( RL.RowToList row list
, RLCommando list row a
) => Commando row a where
commando rec xs = rlCommando (RLProxy :: RLProxy list) rec xs
commando rec xs = rlCommando (Proxy :: Proxy list) rec xs

data Opt (a :: Type) (row :: # Type) = Opt (Optlicative a) (Record row)
data Opt (a :: Type) (row :: Row Type) = Opt (Optlicative a) (Record row)

endOpt :: forall a. Optlicative a -> Opt a ()
endOpt o = Opt o {}
Expand Down
18 changes: 9 additions & 9 deletions src/Node/Optlicative.purs
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ module Node.Optlicative
import Prelude

import Control.Monad.Except (runExcept)
import Data.Array (intercalate)
import Data.Either (Either(..))
import Data.Int (fromNumber)
import Data.List (List(..), (:))
import Data.List as List
import Data.Maybe (Maybe(..))
import Data.Number (isNaN)
import Data.Number as Number
import Data.Traversable (traverse)
import Data.Validation.Semigroup (invalid, isValid, toEither)
import Effect (Effect)
import Effect.Console (error)
import Foreign (F, Foreign, unsafeToForeign)
import Global (isNaN, readFloat)
import Node.Commando (class Commando)
import Node.Commando (class Commando, commando, Opt(..), endOpt) as Exports
import Node.Optlicative.Internal (ddash, ex, except, find, hasHyphen, multipleErrorsToOptErrors, parse, removeAtFor, removeAtForWhile, removeHyphen, startsDash)
Expand All @@ -53,7 +53,7 @@ flag :: String -> Maybe Char -> Optlicative Boolean
flag name mc = Optlicative \ state -> case find ddash name state of
Just i ->
let
{removed, rest} = removeAtFor i 0 state
{rest} = removeAtFor i 0 state
in
{state: rest, val: pure true}
_ -> case mc of
Expand Down Expand Up @@ -86,7 +86,7 @@ int name msg = Optlicative \ state -> case find ddash name state of
{removed, rest} = removeAtForWhile i 1 (not <<< startsDash) state
in
case List.head removed.unparsed of
Just h -> case fromNumber (readFloat h) of
Just h -> case fromNumber =<< Number.fromString h of
Just n -> {state: rest, val: pure n}
_ -> ex name "int" TypeError msg rest
_ -> ex name (show 1) MissingArg msg rest
Expand All @@ -102,9 +102,9 @@ float name msg = Optlicative \ state -> case find ddash name state of
in
case List.head removed.unparsed of
Just h ->
if isNaN (readFloat h)
then ex name "float" TypeError msg rest
else {state: rest, val: pure (readFloat h)}
case Number.fromString h of
Just n | not isNaN n → {state: rest, val: pure n}
_ → ex name "float" TypeError msg rest
_ -> ex name (show 1) MissingArg msg rest
_ -> ex name mempty MissingOpt msg state

Expand All @@ -126,7 +126,7 @@ many parser = Optlicative \optstate -> go parser optstate Nil
go (Optlicative o) s acc =
let
{ state, val } = o s
in
in
case toEither val of
Left _ -> { state, val: pure (List.reverse acc) }
Right v -> go parser state (v:acc)
Expand Down Expand Up @@ -185,7 +185,7 @@ manyF read len name msg = Optlicative \ state -> case find ddash name state of

-- | A convenience function for nicely printing error messages.
renderErrors :: List OptError -> String
renderErrors = intercalate "\n" <<< map renderOptError
renderErrors = List.intercalate "\n" <<< map renderOptError

logErrors :: List OptError -> Effect Unit
logErrors = error <<< renderErrors
Expand Down
29 changes: 14 additions & 15 deletions src/Node/Optlicative/Internal.purs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ removeAtForWhile
-> (String -> Boolean)
-> OptState
-> {removed :: OptState, rest :: OptState}
removeAtForWhile beg end f state@{unparsed} =
removeAtForWhile beg end f {unparsed} =
let
splice = spliceWhile f beg (end + 1) unparsed
in
Expand Down Expand Up @@ -177,27 +177,26 @@ parse
-> {cmd :: Maybe String, value :: Value a}
parse rec prefs argv =
let
args = Array.drop 2 argv
argslist = List.fromFoldable args
{cmds, opts} = partitionArgsList argslist
argslist = List.fromFoldable (Array.drop 2 argv)
args = partitionArgsList argslist
-- Commands
cmdores = commando rec cmds
cmdores = commando rec args.cmds
cmd = _.cmd <$> cmdores
-- Opts
o = maybe prefs.globalOpts _.opt cmdores
{state, val} = unwrap o {unparsed: opts}
unrecCheck = prefs.errorOnUnrecognizedOpts && not (List.null state.unparsed)
value = case prefs.usage, unrecCheck, isValid val of
st = unwrap o {unparsed: args.opts}
unrecCheck = prefs.errorOnUnrecognizedOpts && not (List.null st.state.unparsed)
value = case prefs.usage, unrecCheck, isValid st.val of
Just msg, true, true ->
unrecognizedOpts state <*>
unrecognizedOpts st.state <*>
throwSingleError (Custom msg)
Just msg, true, _ ->
unrecognizedOpts state <*>
unrecognizedOpts st.state <*>
throwSingleError (Custom msg) <*>
val
Just msg, false, false -> throwSingleError (Custom msg) <*> val
Just _, false, _ -> val
_, true, _ -> unrecognizedOpts state <*> val
_, _, _ -> val
st.val
Just msg, false, false -> throwSingleError (Custom msg) <*> st.val
Just _, false, _ -> st.val
_, true, _ -> unrecognizedOpts st.state <*> st.val
_, _, _ -> st.val
in
{cmd, value}
2 changes: 1 addition & 1 deletion src/Node/Optlicative/Types.purs
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ type Preferences a =
{ errorOnUnrecognizedOpts :: Boolean
, usage :: Maybe String
, globalOpts :: Optlicative a
}
}
4 changes: 2 additions & 2 deletions test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Effect (Effect)
import Effect.Console (log)
import Data.List (length)
import Data.Maybe (Maybe(..), maybe)
import Data.Validation.Semigroup (unV)
import Data.Validation.Semigroup (validation)
import Node.Commando (Opt(Opt))
import Node.Optlicative (Optlicative, Preferences, defaultPreferences, flag, logErrors, optlicate, string, many)
import Test.Types (Config(..), ConfigRec, showConfig)
Expand Down Expand Up @@ -56,7 +56,7 @@ main = do
(log "No path parsed")
(\ x -> log "Path parsed" *> log x)
cmd
unV
validation
(\ x -> do
log "Errors found: "
log (show (length x) <> " errors")
Expand Down
2 changes: 1 addition & 1 deletion test/Types.purs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConfigRec =

data Config
= GlobalConfig GlobalConfig
| ConfigOne ConfigOne
| ConfigOne ConfigOne
| ConfigTwo ConfigTwo

showConfig :: Config -> String
Expand Down