mirror of
https://github.com/ChipmunkMC/node-brigadier-commands.git
synced 2024-11-14 19:14:55 -05:00
Implement argument types
Also fixes CommandDispatcher not throwing parse exceptions correctly, RequiredArgumentBuilder returning incorrect objects, and CommandContext.getArgument not returning the correct value
This commit is contained in:
parent
6dc676ef84
commit
d302cf8f37
13 changed files with 281 additions and 5 deletions
|
@ -34,7 +34,7 @@ class CommandDispatcher {
|
||||||
else parse = this.parse(new StringReader(input), source)
|
else parse = this.parse(new StringReader(input), source)
|
||||||
|
|
||||||
if (parse.reader.canRead()) {
|
if (parse.reader.canRead()) {
|
||||||
if (parse.exceptions.size === 1) throw parse.exceptions.values().next()
|
if (parse.exceptions.size === 1) throw parse.exceptions.values().next().value
|
||||||
if (parse.context.range.isEmpty()) throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand.createWithContext(parse.reader)
|
if (parse.context.range.isEmpty()) throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand.createWithContext(parse.reader)
|
||||||
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument.createWithContext(parse.reader)
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument.createWithContext(parse.reader)
|
||||||
}
|
}
|
||||||
|
|
11
lib/arguments/ArgumentType.js
Normal file
11
lib/arguments/ArgumentType.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class ArgumentType {
|
||||||
|
async listSuggestions (context, builder) {
|
||||||
|
return Suggestions.empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
getExamples () {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ArgumentType
|
25
lib/arguments/BoolArgumentType.js
Normal file
25
lib/arguments/BoolArgumentType.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
const ArgumentType = require('./ArgumentType.js')
|
||||||
|
|
||||||
|
const EXAMPLES = ['true', 'false']
|
||||||
|
|
||||||
|
class BoolArgumentType extends ArgumentType {
|
||||||
|
static bool () {
|
||||||
|
return new BoolArgumentType()
|
||||||
|
}
|
||||||
|
|
||||||
|
parse (reader) {
|
||||||
|
return reader.readBoolean()
|
||||||
|
}
|
||||||
|
|
||||||
|
async listSuggestions (context, builder) {
|
||||||
|
if ('true'.startsWith(builder.remainingLowerCase)) builder.suggest('true')
|
||||||
|
if ('false'.startsWith(builder.remainingLowerCase)) builder.suggest('false')
|
||||||
|
return builder.buildPromise()
|
||||||
|
}
|
||||||
|
|
||||||
|
getExamples () {
|
||||||
|
return EXAMPLES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BoolArgumentType
|
43
lib/arguments/DoubleArgumentType.js
Normal file
43
lib/arguments/DoubleArgumentType.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
const ArgumentType = require('./ArgumentType.js')
|
||||||
|
const { CommandSyntaxException } = require('../exceptions')
|
||||||
|
|
||||||
|
const MAXIMUM_DOUBLE = 1.7976931348623157E308
|
||||||
|
const EXAMPLES = ['0', '1.2', '.5', '-1', '-.5', '-1234.56']
|
||||||
|
|
||||||
|
class DoubleArgumentType extends ArgumentType {
|
||||||
|
constructor (minimum, maximum) {
|
||||||
|
super()
|
||||||
|
this.minumum = +minimum
|
||||||
|
this.maximum = +maximum
|
||||||
|
}
|
||||||
|
|
||||||
|
static double (min = -MAXIMUM_DOUBLE, max = MAXIMUM_DOUBLE) {
|
||||||
|
return new DoubleArgumentType(min, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
parse (reader) {
|
||||||
|
const start = reader.cursor
|
||||||
|
const result = reader.readDouble()
|
||||||
|
if (result < this.minumum) {
|
||||||
|
reader.cursor = start
|
||||||
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.doubleTooLow.createWithContext(reader, result, this.minimum)
|
||||||
|
}
|
||||||
|
if (result > this.maximum) {
|
||||||
|
reader.cursor = start
|
||||||
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.doubleTooHigh.createWithContext(reader, result, this.maximum)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
if (this.minumum === -MAXIMUM_DOUBLE && this.maximum === MAXIMUM_DOUBLE) return 'double()'
|
||||||
|
if (this.maximum === MAXIMUM_DOUBLE) return `double(${this.minimum})`
|
||||||
|
return `double(${this.minimum}, ${this.maximum})`
|
||||||
|
}
|
||||||
|
|
||||||
|
getExamples () {
|
||||||
|
return EXAMPLES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DoubleArgumentType
|
43
lib/arguments/FloatArgumentType.js
Normal file
43
lib/arguments/FloatArgumentType.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
const ArgumentType = require('./ArgumentType.js')
|
||||||
|
const { CommandSyntaxException } = require('../exceptions')
|
||||||
|
|
||||||
|
const MAXIMUM_FLOAT = 3.4028235E38
|
||||||
|
const EXAMPLES = ['0', '1.2', '.5', '-1', '-.5', '-1234.56']
|
||||||
|
|
||||||
|
class FloatArgumentType extends ArgumentType {
|
||||||
|
constructor (minimum, maximum) {
|
||||||
|
super()
|
||||||
|
this.minumum = +minimum
|
||||||
|
this.maximum = +maximum
|
||||||
|
}
|
||||||
|
|
||||||
|
static float (min = -MAXIMUM_FLOAT, max = MAXIMUM_FLOAT) {
|
||||||
|
return new FloatArgumentType(min, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
parse (reader) {
|
||||||
|
const start = reader.cursor
|
||||||
|
const result = reader.readFloat()
|
||||||
|
if (result < this.minumum) {
|
||||||
|
reader.cursor = start
|
||||||
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.floatTooLow.createWithContext(reader, result, this.minimum)
|
||||||
|
}
|
||||||
|
if (result > this.maximum) {
|
||||||
|
reader.cursor = start
|
||||||
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.floatTooHigh.createWithContext(reader, result, this.maximum)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
if (this.minumum === -MAXIMUM_FLOAT && this.maximum === MAXIMUM_FLOAT) return 'float()'
|
||||||
|
if (this.maximum === MAXIMUM_FLOAT) return `float(${this.minimum})`
|
||||||
|
return `float(${this.minimum}, ${this.maximum})`
|
||||||
|
}
|
||||||
|
|
||||||
|
getExamples () {
|
||||||
|
return EXAMPLES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = FloatArgumentType
|
44
lib/arguments/IntegerArgumentType.js
Normal file
44
lib/arguments/IntegerArgumentType.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
const ArgumentType = require('./ArgumentType.js')
|
||||||
|
const { CommandSyntaxException } = require('../exceptions')
|
||||||
|
|
||||||
|
const MINIMUM_INT = -2147483648
|
||||||
|
const MAXIMUM_INT = 2147483647
|
||||||
|
const EXAMPLES = ['0', '123', '-123']
|
||||||
|
|
||||||
|
class IntegerArgumentType extends ArgumentType {
|
||||||
|
constructor (minimum, maximum) {
|
||||||
|
super()
|
||||||
|
this.minumum = +minimum
|
||||||
|
this.maximum = +maximum
|
||||||
|
}
|
||||||
|
|
||||||
|
static integer (min = MINIMUM_INT, max = MAXIMUM_INT) {
|
||||||
|
return new IntegerArgumentType(min, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
parse (reader) {
|
||||||
|
const start = reader.cursor
|
||||||
|
const result = reader.readInt()
|
||||||
|
if (result < this.minumum) {
|
||||||
|
reader.cursor = start
|
||||||
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.integerTooLow.createWithContext(reader, result, this.minimum)
|
||||||
|
}
|
||||||
|
if (result > this.maximum) {
|
||||||
|
reader.cursor = start
|
||||||
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.integerTooHigh.createWithContext(reader, result, this.maximum)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
if (this.minumum === MINIMUM_INT && this.maximum === MAXIMUM_INT) return 'integer()'
|
||||||
|
if (this.maximum === MAXIMUM_INT) return `integer(${this.minimum})`
|
||||||
|
return `integer(${this.minimum}, ${this.maximum})`
|
||||||
|
}
|
||||||
|
|
||||||
|
getExamples () {
|
||||||
|
return EXAMPLES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = IntegerArgumentType
|
44
lib/arguments/LongArgumentType.js
Normal file
44
lib/arguments/LongArgumentType.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
const ArgumentType = require('./ArgumentType.js')
|
||||||
|
const { CommandSyntaxException } = require('../exceptions')
|
||||||
|
|
||||||
|
const MINIMUM_LONG = -9223372036854775808n
|
||||||
|
const MAXIMUM_LONG = 9223372036854775807n
|
||||||
|
const EXAMPLES = ['0', '123', '-123']
|
||||||
|
|
||||||
|
class LongArgumentType extends ArgumentType {
|
||||||
|
constructor (minimum, maximum) {
|
||||||
|
super()
|
||||||
|
this.minumum = BigInt(minimum)
|
||||||
|
this.maximum = BigInt(maximum)
|
||||||
|
}
|
||||||
|
|
||||||
|
static long (min = MINIMUM_LONG, max = MAXIMUM_LONG) {
|
||||||
|
return new LongArgumentType(min, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
parse (reader) {
|
||||||
|
const start = reader.cursor
|
||||||
|
const result = reader.readLong()
|
||||||
|
if (result < this.minumum) {
|
||||||
|
reader.cursor = start
|
||||||
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.longTooLow.createWithContext(reader, result, this.minimum)
|
||||||
|
}
|
||||||
|
if (result > this.maximum) {
|
||||||
|
reader.cursor = start
|
||||||
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.longTooHigh.createWithContext(reader, result, this.maximum)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
if (this.minumum === MINIMUM_LONG && this.maximum === MAXIMUM_LONG) return 'long()'
|
||||||
|
if (this.maximum === MAXIMUM_LONG) return `long(${this.minimum})`
|
||||||
|
return `long(${this.minimum}, ${this.maximum})`
|
||||||
|
}
|
||||||
|
|
||||||
|
getExamples () {
|
||||||
|
return EXAMPLES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = LongArgumentType
|
46
lib/arguments/StringArgumentType.js
Normal file
46
lib/arguments/StringArgumentType.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
const ArgumentType = require('./ArgumentType.js')
|
||||||
|
|
||||||
|
class StringArgumentType extends ArgumentType {
|
||||||
|
constructor (type) {
|
||||||
|
super()
|
||||||
|
this.type = type
|
||||||
|
}
|
||||||
|
|
||||||
|
static word () {
|
||||||
|
return new StringArgumentType(StringArgumentType.StringType.SINGLE_WORD)
|
||||||
|
}
|
||||||
|
|
||||||
|
static string () {
|
||||||
|
return new StringArgumentType(StringArgumentType.StringType.QUOTABLE_PHRASE)
|
||||||
|
}
|
||||||
|
|
||||||
|
static greedyString () {
|
||||||
|
return new StringArgumentType(StringArgumentType.StringType.GREEDY_PHRASE)
|
||||||
|
}
|
||||||
|
|
||||||
|
parse (reader) {
|
||||||
|
if (this.type === StringArgumentType.StringType.GREEDY_PHRASE) {
|
||||||
|
const text = reader.getRemaining()
|
||||||
|
reader.cursor = reader.getTotalLength()
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type === StringArgumentType.StringType.SINGLE_WORD) {
|
||||||
|
return reader.readUnquotedString()
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader.readString()
|
||||||
|
}
|
||||||
|
|
||||||
|
getExamples () {
|
||||||
|
return this.type.examples
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringType = {
|
||||||
|
SINGLE_WORD: { examples: ['word', 'words_with_underscores'] },
|
||||||
|
QUOTABLE_PHRASE: { examples: ['"quoted phrase"', 'word', '""'] },
|
||||||
|
GREEDY_PHRASE: { examples: ['word', 'words with spaces', '"and symbols"'] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = StringArgumentType
|
17
lib/arguments/index.js
Normal file
17
lib/arguments/index.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
const ArgumentType = require('./ArgumentType.js')
|
||||||
|
const BoolArgumentType = require('./BoolArgumentType.js')
|
||||||
|
const DoubleArgumentType = require('./DoubleArgumentType.js')
|
||||||
|
const FloatArgumentType = require('./FloatArgumentType.js')
|
||||||
|
const IntegerArgumentType = require('./IntegerArgumentType.js')
|
||||||
|
const LongArgumentType = require('./LongArgumentType.js')
|
||||||
|
const StringArgumentType = require('./StringArgumentType.js')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
ArgumentType,
|
||||||
|
BoolArgumentType,
|
||||||
|
DoubleArgumentType,
|
||||||
|
FloatArgumentType,
|
||||||
|
IntegerArgumentType,
|
||||||
|
LongArgumentType,
|
||||||
|
StringArgumentType
|
||||||
|
}
|
|
@ -11,12 +11,13 @@ class RequiredArgumentBuilder extends ArgumentBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
static argument (name, type) {
|
static argument (name, type) {
|
||||||
return new RequiredArgumentBuilder(name)
|
return new RequiredArgumentBuilder(name, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
build () {
|
build () {
|
||||||
const result = new ArgumentCommandNode({
|
const result = new ArgumentCommandNode({
|
||||||
literal: this.literal,
|
name: this.name,
|
||||||
|
type: this.type,
|
||||||
command: this.command,
|
command: this.command,
|
||||||
requirement: this.requirement,
|
requirement: this.requirement,
|
||||||
redirect: this.target,
|
redirect: this.target,
|
||||||
|
|
|
@ -42,7 +42,7 @@ class CommandContext {
|
||||||
throw new ReferenceError(`No such argument '${name}' exists on this command`)
|
throw new ReferenceError(`No such argument '${name}' exists on this command`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return argument
|
return argument.result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const exceptions = require('./exceptions')
|
const exceptions = require('./exceptions')
|
||||||
const StringReader = require('./StringReader.js')
|
const StringReader = require('./StringReader.js')
|
||||||
|
const _arguments = require('./arguments')
|
||||||
const context = require('./context')
|
const context = require('./context')
|
||||||
const suggestion = require('./suggestion')
|
const suggestion = require('./suggestion')
|
||||||
const tree = require('./tree')
|
const tree = require('./tree')
|
||||||
|
@ -9,6 +10,7 @@ const LiteralMessage = require('./LiteralMessage.js')
|
||||||
const ParseResults = require('./ParseResults.js')
|
const ParseResults = require('./ParseResults.js')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
arguments: _arguments,
|
||||||
builder,
|
builder,
|
||||||
context,
|
context,
|
||||||
exceptions,
|
exceptions,
|
||||||
|
|
|
@ -29,7 +29,7 @@ class CommandNode {
|
||||||
} else {
|
} else {
|
||||||
this.children[node.name] = node
|
this.children[node.name] = node
|
||||||
if (node instanceof LiteralCommandNode) this.literals[node.name] = node
|
if (node instanceof LiteralCommandNode) this.literals[node.name] = node
|
||||||
else if (node instanceof ArgumentCommandNode) this.literals[node.name] = node
|
else if (node instanceof ArgumentCommandNode) this.arguments[node.name] = node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue