Start working on the parsing logic

This commit is contained in:
Alexander Söderberg 2020-08-31 16:07:35 +02:00
parent d98f5d9840
commit e6f7d04495
No known key found for this signature in database
GPG key ID: C0207FF7EA146678
5 changed files with 213 additions and 4 deletions

View file

@ -1,14 +1,37 @@
//
// MIT License
//
// Copyright (c) 2020 IntellectualSites
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands; package com.intellectualsites.commands;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.intellectualsites.commands.components.CommandComponent; import com.intellectualsites.commands.components.CommandComponent;
import com.intellectualsites.commands.components.StaticComponent; import com.intellectualsites.commands.components.StaticComponent;
import com.intellectualsites.commands.parser.ComponentParseResult;
import com.intellectualsites.commands.sender.CommandSender;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Collections; import java.util.*;
import java.util.LinkedList;
import java.util.List;
/** /**
* Tree containing all commands and command paths * Tree containing all commands and command paths
@ -29,6 +52,41 @@ public class CommandTree {
return new CommandTree(); return new CommandTree();
} }
public Optional<Command> parse(@Nonnull final String[] args) {
final CommandSender tempSender = new CommandSender() {
};
final Queue<String> commandQueue = new LinkedList<>(Arrays.asList(args));
return parseCommand(tempSender, commandQueue, this.internalTree);
}
private Optional<Command> parseCommand(@Nonnull final CommandSender commandSender, @Nonnull final Queue<String> commandQueue,
@Nonnull final Node<CommandComponent<?>> root) {
final Iterator<Node<CommandComponent<?>>> childIterator = root.getChildren().iterator();
if (childIterator.hasNext()) {
while (childIterator.hasNext()) {
final Node<CommandComponent<?>> child = childIterator.next();
if (child.getValue() != null) {
final ComponentParseResult<?> result = child.getValue().getParser().parse(commandSender, commandQueue);
if (result.getParsedValue().isPresent()) {
/* TODO: Add to some context */
return this.parseCommand(commandSender, commandQueue, child);
} else if (result.getFailure().isPresent() && root.children.size() == 1) {
/* Return the error somehow :D */
}
}
}
} else {
/* We are at the bottom. Check if there's a command attached, in which case we're done */
if (root.getValue() != null && root.getValue().getOwningCommand() != null) {
return Optional.of(root.getValue().getOwningCommand());
} else {
/* TODO: Indicate that we could not resolve the command here */
}
}
return Optional.empty();
}
/** /**
* Insert a new command into the command tree * Insert a new command into the command tree
* *

View file

@ -23,9 +23,15 @@
// //
package com.intellectualsites.commands.components; package com.intellectualsites.commands.components;
import com.intellectualsites.commands.parser.ComponentParseResult;
import com.intellectualsites.commands.parser.ComponentParser; import com.intellectualsites.commands.parser.ComponentParser;
import com.intellectualsites.commands.sender.CommandSender;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Queue;
import java.util.Set;
public final class StaticComponent extends CommandComponent<String> { public final class StaticComponent extends CommandComponent<String> {
@ -36,7 +42,27 @@ public final class StaticComponent extends CommandComponent<String> {
private static final class StaticComponentParser implements ComponentParser<String> { private static final class StaticComponentParser implements ComponentParser<String> {
private final String name;
private final Set<String> acceptedStrings = new HashSet<>();
private StaticComponentParser(@Nonnull final String name, @Nonnull final String ... aliases) { private StaticComponentParser(@Nonnull final String name, @Nonnull final String ... aliases) {
this.acceptedStrings.add(this.name = name);
this.acceptedStrings.addAll(Arrays.asList(aliases));
}
@Nonnull @Override public ComponentParseResult<String> parse(@Nonnull final CommandSender sender, @Nonnull final Queue<String> inputQueue) {
final String string = inputQueue.peek();
if (string == null) {
return ComponentParseResult.failure(this.name);
}
for (final String acceptedString : this.acceptedStrings) {
if (string.equalsIgnoreCase(acceptedString)) {
// Remove the head of the queue
inputQueue.remove();
return ComponentParseResult.success(this.name);
}
}
return ComponentParseResult.failure(this.name);
} }
} }

View file

@ -0,0 +1,83 @@
//
// MIT License
//
// Copyright (c) 2020 IntellectualSites
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.parser;
import javax.annotation.Nonnull;
import java.util.Optional;
public abstract class ComponentParseResult<T> {
private ComponentParseResult() {
}
@Nonnull public static <T> ComponentParseResult<T> failure(@Nonnull final String failure) {
return new ParseFailure<>(failure);
}
@Nonnull public static <T> ComponentParseResult<T> success(@Nonnull final T value) {
return new ParseSuccess<>(value);
}
@Nonnull public abstract Optional<T> getParsedValue();
@Nonnull public abstract Optional<String> getFailure();
private static final class ParseSuccess<T> extends ComponentParseResult<T> {
private final T value;
private ParseSuccess(@Nonnull final T value) {
this.value = value;
}
@Nonnull @Override public Optional<T> getParsedValue() {
return Optional.of(this.value);
}
@Nonnull @Override public Optional<String> getFailure() {
return Optional.empty();
}
}
private static final class ParseFailure<T> extends ComponentParseResult<T> {
private final String failure;
private ParseFailure(@Nonnull final String failure) {
this.failure = failure;
}
@Nonnull @Override public Optional<T> getParsedValue() {
return Optional.empty();
}
@Nonnull @Override public Optional<String> getFailure() {
return Optional.of(this.failure);
}
}
}

View file

@ -23,5 +23,20 @@
// //
package com.intellectualsites.commands.parser; package com.intellectualsites.commands.parser;
public interface ComponentParser<T> { import com.intellectualsites.commands.sender.CommandSender;
import javax.annotation.Nonnull;
import java.util.Queue;
@FunctionalInterface public interface ComponentParser<T> {
/**
* Parse command input into a command result
*
* @param sender Sender who sent the command
* @param inputQueue The queue of arguments
* @return Parsed command result
*/
@Nonnull ComponentParseResult<T> parse(@Nonnull CommandSender sender, @Nonnull Queue<String> inputQueue);
} }

View file

@ -0,0 +1,27 @@
//
// MIT License
//
// Copyright (c) 2020 IntellectualSites
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.sender;
public interface CommandSender {
}