partially applied string and float args to NAT commands
This commit is contained in:
@@ -2,6 +2,7 @@ package nat;
|
|||||||
|
|
||||||
import kiss.Prelude;
|
import kiss.Prelude;
|
||||||
import kiss.List;
|
import kiss.List;
|
||||||
|
import kiss.Stream;
|
||||||
import haxe.Constraints;
|
import haxe.Constraints;
|
||||||
import haxe.DynamicAccess;
|
import haxe.DynamicAccess;
|
||||||
import uuid.Uuid;
|
import uuid.Uuid;
|
||||||
@@ -25,6 +26,9 @@ enum CommandArgType {
|
|||||||
// TODO VarTag
|
// TODO VarTag
|
||||||
|
|
||||||
// TODO playground name -- choose from archive.playgrounds
|
// TODO playground name -- choose from archive.playgrounds
|
||||||
|
|
||||||
|
// Then again the more of these I add the more convoluted CollectAndValidateArgs gets,
|
||||||
|
// and the more stream reader methods I need to write
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef CommandArg = {
|
typedef CommandArg = {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
(load "Lib.kiss")
|
(load "Lib.kiss")
|
||||||
|
|
||||||
(method :Void _collectAndValidateArg [:CommandArg arg :Dynamic->Void continuation]
|
(method :Void _collectAndValidateArg [:CommandArg arg :Stream stream :Dynamic->Void continuation]
|
||||||
(case arg.type
|
(case arg.type
|
||||||
(SelectedEntry
|
(SelectedEntry
|
||||||
(if (= 1 _selectedEntries.length)
|
(if (= 1 _selectedEntries.length)
|
||||||
@@ -15,32 +15,39 @@
|
|||||||
(continuation _selectedEntries)))
|
(continuation _selectedEntries)))
|
||||||
((Text maxLength)
|
((Text maxLength)
|
||||||
(unless maxLength (set maxLength Math.POSITIVE_INFINITY))
|
(unless maxLength (set maxLength Math.POSITIVE_INFINITY))
|
||||||
(ui.enterText
|
(stream.dropWhitespace)
|
||||||
"${arg.name} (up to ${maxLength} characters):"
|
(localFunction :Void trySubmit [text]
|
||||||
(lambda :Void [text]
|
(if !(<= text.length maxLength)
|
||||||
(if !(<= text.length maxLength)
|
(ui.reportError "The requested command expected a string up to $maxLength characters long. You entered: $text.length characters")
|
||||||
(ui.reportError "The requested command expected a string up to $maxLength characters long. You entered: $text.length characters")
|
(continuation text)))
|
||||||
(continuation text)))
|
(if (or (stream.isEmpty) (stream.dropStringIf "_"))
|
||||||
maxLength))
|
// If no text argument was pre-supplied, use the ui for it
|
||||||
|
(ui.enterText
|
||||||
|
"${arg.name} (up to ${maxLength} characters):"
|
||||||
|
trySubmit
|
||||||
|
maxLength))
|
||||||
|
(trySubmit (readString stream)))
|
||||||
((VarText maxLength)
|
((VarText maxLength)
|
||||||
(unless maxLength (set maxLength Math.POSITIVE_INFINITY))
|
(unless maxLength (set maxLength Math.POSITIVE_INFINITY))
|
||||||
(let [collectedText
|
(let [collectedText []]
|
||||||
[]
|
|
||||||
&mut :Void->Void enterTextAgain
|
|
||||||
null
|
(localFunction :Void enterTextAgain []
|
||||||
_enterTextAgain
|
(localFunction :Void trySubmit [text]
|
||||||
->:Void
|
(if !text
|
||||||
|
(continuation collectedText)
|
||||||
|
(if !(<= text.length maxLength)
|
||||||
|
(ui.reportError "The requested command expected a list of strings up to $maxLength characters long. You entered: $text.length characters")
|
||||||
|
{(collectedText.push text)
|
||||||
|
(enterTextAgain)})))
|
||||||
|
|
||||||
|
(if (or (stream.isEmpty) (stream.dropStringIf "_"))
|
||||||
|
// If no vartext argument was pre-supplied, use the ui for it
|
||||||
(ui.enterText
|
(ui.enterText
|
||||||
"${arg.name} (up to ${maxLength} characters):"
|
"${arg.name} (up to ${maxLength} characters):"
|
||||||
(lambda :Void [text]
|
trySubmit
|
||||||
(if !text
|
maxLength)
|
||||||
(continuation collectedText)
|
(trySubmit (readString stream))))
|
||||||
(if !(<= text.length maxLength)
|
|
||||||
(ui.reportError "The requested command expected a list of strings up to $maxLength characters long. You entered: $text.length characters")
|
|
||||||
{(collectedText.push text)
|
|
||||||
(enterTextAgain)})))
|
|
||||||
maxLength)]
|
|
||||||
(set enterTextAgain _enterTextAgain)
|
|
||||||
(enterTextAgain)))
|
(enterTextAgain)))
|
||||||
((Number min max inStepsOf)
|
((Number min max inStepsOf)
|
||||||
(unless min (set min Math.NEGATIVE_INFINITY))
|
(unless min (set min Math.NEGATIVE_INFINITY))
|
||||||
@@ -50,10 +57,8 @@
|
|||||||
(+= prompt " in steps of ${inStepsOf}"))
|
(+= prompt " in steps of ${inStepsOf}"))
|
||||||
(+= prompt "):")
|
(+= prompt "):")
|
||||||
|
|
||||||
(ui.enterNumber
|
(localFunction :Void trySubmit [number]
|
||||||
prompt
|
(let [minMaxError
|
||||||
(lambda :Void [number]
|
|
||||||
(let [minMaxError
|
|
||||||
"The requested command expected a number between $min and $max"
|
"The requested command expected a number between $min and $max"
|
||||||
stepError
|
stepError
|
||||||
"$minMaxError in steps of $inStepsOf"
|
"$minMaxError in steps of $inStepsOf"
|
||||||
@@ -66,9 +71,17 @@
|
|||||||
(ui.reportError "${stepError}$youEntered")
|
(ui.reportError "${stepError}$youEntered")
|
||||||
(ui.reportError "${minMaxError}$youEntered"))
|
(ui.reportError "${minMaxError}$youEntered"))
|
||||||
(continuation number))))
|
(continuation number))))
|
||||||
min
|
|
||||||
max
|
// If no text argument was pre-supplied, use the ui for it
|
||||||
inStepsOf)))
|
(if (or (stream.isEmpty) (stream.dropStringIf "_"))
|
||||||
|
(ui.enterNumber
|
||||||
|
prompt
|
||||||
|
trySubmit
|
||||||
|
min
|
||||||
|
max
|
||||||
|
inStepsOf)
|
||||||
|
(trySubmit (readNumber stream)))))
|
||||||
|
|
||||||
(OneEntry
|
(OneEntry
|
||||||
(ui.chooseEntry
|
(ui.chooseEntry
|
||||||
"${arg.name}:"
|
"${arg.name}:"
|
||||||
@@ -92,17 +105,36 @@
|
|||||||
max))
|
max))
|
||||||
(null)))
|
(null)))
|
||||||
|
|
||||||
(method :Void->Void _composeArgCollector [:Array<Dynamic> collectedArgs :CommandArg arg :Void->Void lastCollector]
|
// TODO try catch and ui.reportError
|
||||||
(lambda :Void []
|
// TODO maaaybe support escape sequences?
|
||||||
(_collectAndValidateArg arg ->:Void [:Dynamic argValue] {(collectedArgs.push argValue) (lastCollector)})))
|
(function readString [:Stream stream]
|
||||||
|
(let [terminator
|
||||||
|
(case (stream.takeChars 1)
|
||||||
|
((Some "\"") "\"")
|
||||||
|
((Some "'") "'")
|
||||||
|
(otherwise (throw "string arg must start with \" or '")))]
|
||||||
|
(case (stream.takeUntilAndDrop terminator)
|
||||||
|
((Some s) s)
|
||||||
|
(otherwise (throw "string arg must end with $terminator")))))
|
||||||
|
|
||||||
(method :Void tryRunCommand [:String commandName]
|
// TODO try catch and ui.reportError
|
||||||
(let [lowerCommandName (commandName.toLowerCase)]
|
(function readNumber [:Stream stream]
|
||||||
|
(Std.parseFloat (case (stream.takeUntilOneOf [" "] true) ((Some f) f) (otherwise ""))))
|
||||||
|
|
||||||
|
(method :Void->Void _composeArgCollector [:Array<Dynamic> collectedArgs :CommandArg arg :Stream stream :Void->Void lastCollector]
|
||||||
|
(lambda :Void []
|
||||||
|
(_collectAndValidateArg arg stream ->:Void [:Dynamic argValue] {(collectedArgs.push argValue) (lastCollector)})))
|
||||||
|
|
||||||
|
(method :Void tryRunCommand [:String command]
|
||||||
|
(let [parts (command.split " ")
|
||||||
|
commandName (parts.shift)
|
||||||
|
stream (Stream.fromString (parts.join " "))
|
||||||
|
lowerCommandName (commandName.toLowerCase)]
|
||||||
(if (commands.exists lowerCommandName)
|
(if (commands.exists lowerCommandName)
|
||||||
(_runCommand (dictGet commands lowerCommandName))
|
(_runCommand (dictGet commands lowerCommandName) stream)
|
||||||
(ui.reportError "$commandName is not a valid command"))))
|
(ui.reportError "$commandName is not a valid command"))))
|
||||||
|
|
||||||
(method :Void _runCommand [:Command command]
|
(method :Void _runCommand [:Command command :Stream stream]
|
||||||
(let [collectedArgs
|
(let [collectedArgs
|
||||||
[]
|
[]
|
||||||
&mut lastCollector
|
&mut lastCollector
|
||||||
@@ -111,7 +143,7 @@
|
|||||||
(when lastChangeSet (ui.handleChanges archive lastChangeSet)))]
|
(when lastChangeSet (ui.handleChanges archive lastChangeSet)))]
|
||||||
// To facilitate asynchronous arg input via UI, we need to construct an insanely complicated nested callback to give the UI
|
// To facilitate asynchronous arg input via UI, we need to construct an insanely complicated nested callback to give the UI
|
||||||
(doFor arg (reverse command.args)
|
(doFor arg (reverse command.args)
|
||||||
(set lastCollector (_composeArgCollector collectedArgs arg lastCollector)))
|
(set lastCollector (_composeArgCollector collectedArgs arg stream lastCollector)))
|
||||||
(lastCollector)))
|
(lastCollector)))
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user