command handler MEAT

This commit is contained in:
noolaan 2020-04-11 07:56:52 -06:00
parent bda64c6df6
commit 8fbe72b327
2 changed files with 140 additions and 42 deletions

View File

@ -20,6 +20,13 @@ class PingCommand extends Command {
type: 'INTEGER', type: 'INTEGER',
types: ['FLAG', 'VERBAL'], types: ['FLAG', 'VERBAL'],
default: 0 default: 0
}),
new Argument(client, {
name: 'carrot',
aliases: ['cars', 'carrots'],
type: 'STRING',
required: true,
types: ['FLAG', 'VERBAL']
}) })
] ]
}); });

View File

@ -1,5 +1,5 @@
const { stripIndents } = require('common-tags'); const { stripIndents } = require('common-tags');
const { escapeRegex } = require('escape-string-regexp'); const escapeRegex = require('escape-string-regexp');
const { Observer } = require('../../../interfaces/'); const { Observer } = require('../../../interfaces/');
@ -124,70 +124,160 @@ class CommandHandler extends Observer {
const parsedFlags = {}; const parsedFlags = {};
const { shortFlags, longFlags, keys } = await this._createFlags(command.arguments); const { shortFlags, longFlags, keys } = await this._createFlags(command.arguments);
const regex = new RegExp(`([0-9]*)(${Object.keys(longFlags).map(k=>escapeRegex(k)).join('|')})([0-9]*)`, 'i');
// -prune 50 -c #test console.log(regex);
// -prune 50 -b -c #test
let currentArgument = null; let currentArgument = null;
for(const word of args) { let params = [];
for(let i=0; i<args.length; i++) {
const word = args[i];
if(!word) continue;
const [one,two,...chars] = word.split(''); const [one,two,...chars] = word.split('');
if(one === '-' && two !== '-') { //short flag maybe? if(one === '-' && two !== '-') {
const name = [ two, ...chars ].join(''); const name = [ two, ...chars ].join('');
if(currentArgument) {
if(currentArgument.required) {
//Cannot use another flag after a required flag.
//Handle requirement error for currentArgument.
}
}
if(!keys.includes(name)) continue; if(!keys.includes(name)) continue;
currentArgument = shortFlags[name]; currentArgument = shortFlags[name];
if(currentArgument.required && !args[i+1]) {
} else if(one === '-' && two === '-') { //long flag maybe? console.error(`Argument ${currentArgument.name} is required and was not provided.`);
if(currentArgument.required) { return undefined;
//Cannot use another flag after a required flag.
//Handle requirement error for currentArgument.
} }
const name = chars.join(''); continue;
} else if((one === '-' && two === '-') || one === '—') { //Handling for "long dash" on mobile phones x_x
const name = one === '—'
? [ two, ...chars ].join('').toLowerCase()
: chars.join('').toLowerCase(); //can convert to lowercase now that shortFlags are out of the way.
if(!keys.includes(name)) continue; if(!keys.includes(name)) continue;
currentArgument = longFlags[name]; currentArgument = longFlags[name];
if(currentArgument.required && !args[i+1]) {
console.error(`Argument ${currentArgument.name} is required and was not provided.`);
return undefined;
}
continue;
} else { } else {
const regex = new RegExp('([0-9]*)([a-zA-Z]+)([0-9]*)', 'g');
let match = regex.exec(word); let match = regex.exec(word);
if(currentArgument && !match) { if(match && match[2]) {
await this._handleTypeParsing(currentArgument, word); currentArgument = longFlags[match[2]];
if(!currentArgument.infinite) currentArgument = null; if(params.length > 0 && ['INTEGER', 'FLOAT'].includes(currentArgument.type)) { //15 pts
console.log("asgsaiughasiguassag")
const lastItem = params[params.length-1];
const beforeError = await this._handleTypeParsing(currentArgument, lastItem);
if(beforeError) {
continue;
} else {
params.pop();
currentArgument.value = lastItem;
parsedArguments.push(currentArgument);
currentArgument = null;
continue;
}
}
const value = match[1] || match[3];
const error = await this._handleTypeParsing(currentArgument, value);
if(value) {
if(error) {
if(currentArgument.required) {
console.error(`Argument ${currentArgument.name} is required and failed to meet requirements.`);
return undefined;
} else {
parsedArguments.push(currentArgument);
currentArgument = null;
continue;
}
} else {
currentArgument.value = value;
parsedArguments.push(currentArgument);
currentArgument = null;
continue;
}
} else {
continue;
}
} else {
if(currentArgument) {
const error = await this._handleTypeParsing(currentArgument, word);
if(error) {
if(currentArgument.default) {
params.push(word);
currentArgument.value = currentArgument.default;
parsedArguments.push(currentArgument);
currentArgument = null;
continue;
}
if(currentArgument.required) {
if(currentArgument.infinite) {
if(currentArgument.value.length === 0) {
console.error(`1 Argument ${currentArgument.name} is required and failed to meet requirements.`);
return undefined;
} else {
parsedArguments.push(currentArgument);
currentArgument = null;
params.push(word);
continue;
}
} else {
console.error(`2 Argument ${currentArgument.name} is required and failed to meet requirements.`);
return undefined;
}
} else {
currentArgument = null;
params.push(word);
continue;
}
} else {
if(currentArgument.infinite) continue;
parsedArguments.push(currentArgument);
currentArgument = null;
continue;
}
} else {
params.push(word);
continue;
}
} }
if(!keys[match[2]]) {
//do sometihng there
}
currentArgument = longFlags[match[2]];
const value = match[1] || match[3];
} }
} }
message.channel.send(stripIndents`**arguments:** ${parsedArguments.map(a=>`${a.name}: ${a.value}`).join(' | ')}
**words:** ${params.join(', ')}`);
} }
async _handleTypeParsing(argument, string) { async _handleTypeParsing(argument, string) {
const { error, value } = await this.constructor.parseType(argument, string); //Cannot access static functions through "this". const parse = async (argument, string) => {
if(error) {
//Failed to parse correctly. prompt.invalid const { error, value } = await this.constructor.parseType(argument.type, string); //Cannot access static functions through "this".
if(error) return { error: true };
if(['INTEGER', 'FLOAT'].includes(argument.type)) {
const { min, max } = argument;
if(value > max && max !== null) {
return { error: true };
}
if(value < min && min !== null) {
return { error: true };
}
}
return { error: false, value };
} }
if(['INTEGER', 'FLOAT'].includes(argument.type)) { const { error, value } = await parse(argument, string);
const { min, max } = argument;
if(value > max) { if(!error) {
//Failed to parse correctly. prompt.invalid argument.infinite
} ? argument.value.push(value)
if(value < min) { : argument.value = value;
//Failed to parse correctly. prompt.invalid
}
} }
return error;
} }
async _createFlags(args) { async _createFlags(args) {
@ -254,6 +344,7 @@ class CommandHandler extends Observer {
} }
} }
return await types[type](str); return await types[type](str);
} }