1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

adfsfasdfaSDQAWERTERYTUYghyubnjnrdfxcv etgvbhy0ujn-

This commit is contained in:
mat 2022-01-11 00:01:47 -06:00
parent 60b129b3a6
commit cc4fe62fc8
14 changed files with 299 additions and 29 deletions

View file

@ -7,7 +7,9 @@ use crate::{
};
pub trait Types {
fn bool(value: bool) -> Self;
fn bool(value: bool) -> Self
where
Self: Sized;
}
/*
@ -28,7 +30,7 @@ enum BrigadierTypes {
pub trait ArgumentType<T>
where
Self: Sized,
T: Types,
T: Types + ?Sized,
{
// T parse(StringReader reader) throws CommandSyntaxException;

View file

@ -33,13 +33,13 @@ where
// builder.suggest("false");
// }
// return builder.buildFuture();
if "true".starts_with(builder.get_remaining_lower_case()) {
if "true".starts_with(builder.remaining_lowercase()) {
builder.suggest("true");
}
if "false".starts_with(builder.get_remaining_lower_case()) {
if "false".starts_with(builder.remaining_lowercase()) {
builder.suggest("false");
}
Ok(builder.build_future())
Ok(builder.build())
}
fn get_examples(&self) -> Vec<String> {

View file

@ -14,17 +14,20 @@ pub struct CommandContext<'a, S, T> {
command: &'a dyn Command<S, T>,
arguments: HashMap<String, ParsedArgument<T>>,
root_node: &'a dyn CommandNode<S, T>,
nodes: Vec<ParsedCommandNode<'a, S, T>>,
nodes: Vec<ParsedCommandNode<S, T>>,
range: StringRange,
child: Option<CommandContext<'a, S, T>>,
child: Option<&'a CommandContext<'a, S, T>>,
modifier: Option<&'a dyn RedirectModifier<S, T>>,
forks: bool,
}
impl<S, T> CommandContext<'_, S, T> {
impl<S, T> CommandContext<'_, S, T>
where
S: PartialEq,
{
pub fn clone_for(&self, source: S) -> Self {
if self.source == source {
return self.clone();
return *self;
}
Self {
source,

View file

@ -28,7 +28,7 @@ use super::{
pub struct CommandContextBuilder<'a, S, T> {
arguments: HashMap<String, ParsedArgument<T>>,
root_node: &'a dyn CommandNode<S, T>,
nodes: Vec<ParsedCommandNode<'a, S, T>>,
nodes: Vec<ParsedCommandNode<S, T>>,
dispatcher: CommandDispatcher<'a, S, T>,
source: S,
command: Box<dyn Command<S, T>>,

View file

@ -1,6 +1,6 @@
use super::string_range::StringRange;
#[derive(PartialEq, Eq, Hash)]
#[derive(PartialEq, Eq, Hash, Clone)]
pub struct ParsedArgument<T> {
range: StringRange,
// T is an item in an enum

View file

@ -1,14 +1,13 @@
use super::string_range::StringRange;
use crate::tree::command_node::CommandNode;
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
pub struct ParsedCommandNode<'a, S, T> {
node: &'a dyn CommandNode<S, T>,
pub struct ParsedCommandNode<S, T> {
node: Box<dyn CommandNode<S, T>>,
range: StringRange,
}
impl<S, T> ParsedCommandNode<'_, S, T> {
fn new(node: &dyn CommandNode<S, T>, range: StringRange) -> Self {
impl<S, T> ParsedCommandNode<S, T> {
fn new(node: dyn CommandNode<S, T>, range: StringRange) -> Self {
Self { node, range }
}

View file

@ -1,6 +1,6 @@
use std::cmp;
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StringRange {
start: usize,
end: usize,

View file

@ -1,5 +1,6 @@
use std::rc::Rc;
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct Message(Rc<String>);
impl Message {

View file

@ -0,0 +1,90 @@
use std::cmp;
use crate::{context::string_range::StringRange, message::Message};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Suggestion {
range: StringRange,
text: String,
tooltip: Option<Message>,
}
impl Suggestion {
pub fn new(range: StringRange, text: String) -> Suggestion {
Suggestion {
range,
text,
tooltip: None,
}
}
pub fn new_with_tooltip(range: StringRange, text: String, tooltip: Message) -> Suggestion {
Suggestion {
range,
text,
tooltip: Some(tooltip),
}
}
pub fn range(&self) -> &StringRange {
&self.range
}
pub fn text(&self) -> &String {
&self.text
}
pub fn tooltip(&self) -> Option<&Message> {
self.tooltip.as_ref()
}
pub fn apply(&self, input: &str) -> String {
if self.range.start() == 0 && self.range.end() == input.len() {
return self.text.clone();
}
let mut result = String::new();
if self.range.start() > 0 {
result.push_str(&input[0..self.range.start()]);
}
result.push_str(&self.text);
if self.range.end() < input.len() {
result.push_str(&input[self.range.end()..]);
}
result
}
pub fn expand(&self, command: &str, range: StringRange) -> Suggestion {
if range == self.range {
return self.clone();
}
let mut result = String::new();
if range.start() < self.range.start() {
result.push_str(&command[range.start()..self.range.start()]);
}
result.push_str(&self.text);
if range.end() > self.range.end() {
result.push_str(&command[self.range.end()..range.end()]);
}
Suggestion {
range,
text: result,
tooltip: self.tooltip.clone(),
}
}
pub fn compare_ignore_case(&self, b: &Suggestion) -> cmp::Ordering {
self.text.to_lowercase().cmp(&b.text.to_lowercase())
}
}
impl PartialOrd for Suggestion {
fn partial_cmp(&self, other: &Suggestion) -> Option<cmp::Ordering> {
Some(self.text.cmp(&other.text))
}
}
impl Ord for Suggestion {
fn cmp(&self, other: &Suggestion) -> cmp::Ordering {
self.text.cmp(&other.text)
}
}

View file

@ -1 +1,59 @@
use std::cmp;
use crate::{context::string_range::StringRange, message::Message};
pub struct Suggestions {}
// #[cfg(test)]
// mod tests {
// use crate::suggestion::suggestion::Suggestion;
// use super::*;
// #[test]
// fn merge_empty() {
// let merged = Suggestions::merge("foo b", vec![]);
// assert_eq!(merged.is_empty(), true);
// }
// #[test]
// fn merge_single() {
// let suggestions = Suggestions::new(StringRange::at(5), "ar".to_string());
// let merged = Suggestions::merge("foo b", vec![suggestions]);
// assert_eq!(merged, suggestions);
// }
// #[test]
// fn merge_multiple() {
// let a = Suggestions::new(
// StringRange::at(5),
// vec![
// Suggestion::new(StringRange::at(5), "ar".to_string()),
// Suggestion::new(StringRange::at(5), "az".to_string()),
// Suggestion::new(StringRange::at(5), "Az".to_string()),
// ],
// );
// let b = Suggestions::new(
// StringRange::between(4, 5),
// vec![
// Suggestion::new(StringRange::between(4, 5), "foo".to_string()),
// Suggestion::new(StringRange::between(4, 5), "qux".to_string()),
// Suggestion::new(StringRange::between(4, 5), "apple".to_string()),
// Suggestion::new(StringRange::between(4, 5), "Bar".to_string()),
// ],
// );
// let merged = Suggestions::merge("foo b", vec![a, b]);
// assert_eq!(
// merged.get_list(),
// vec![
// Suggestion::new(StringRange::between(4, 5), "apple".to_string()),
// Suggestion::new(StringRange::between(4, 5), "bar".to_string()),
// Suggestion::new(StringRange::between(4, 5), "Bar".to_string()),
// Suggestion::new(StringRange::between(4, 5), "baz".to_string()),
// Suggestion::new(StringRange::between(4, 5), "bAz".to_string()),
// Suggestion::new(StringRange::between(4, 5), "foo".to_string()),
// Suggestion::new(StringRange::between(4, 5), "qux".to_string()),
// ]
// );
// }
// }

View file

@ -1 +1,114 @@
pub struct SuggestionsBuilder {}
use crate::context::string_range::StringRange;
use super::{suggestion::Suggestion, suggestions::Suggestions};
pub struct SuggestionsBuilder {
input: String,
input_lowercase: String,
start: usize,
remaining: String,
remaining_lowercase: String,
result: Vec<Suggestion>,
}
impl SuggestionsBuilder {
pub fn new_with_lowercase(
input: String,
input_lowercase: String,
start: usize,
) -> SuggestionsBuilder {
SuggestionsBuilder {
input,
input_lowercase,
start,
remaining: input.get(start..).unwrap().to_string(),
remaining_lowercase: input_lowercase.get(start..).unwrap().to_string(),
result: Vec::new(),
}
}
pub fn new(input: String, start: usize) -> SuggestionsBuilder {
SuggestionsBuilder::new_with_lowercase(input, input.to_lowercase(), start)
}
pub fn input(&self) -> &str {
&self.input
}
pub fn start(&self) -> usize {
self.start
}
pub fn remaining(&self) -> &str {
&self.remaining
}
pub fn remaining_lowercase(&self) -> &str {
&self.remaining_lowercase
}
pub fn build(&self) -> Suggestions {
Suggestions::create(self.input(), self.result)
}
pub fn suggest(&mut self, text: &str) -> &mut SuggestionsBuilder {
if text == self.remaining {
return self;
}
self.result.push(Suggestion::new(
StringRange::between(self.start, self.input.len()),
text,
));
self
}
pub fn suggest_with_tooltip(&mut self, text: &str, tooltip: &str) -> &mut SuggestionsBuilder {
if text == self.remaining {
return self;
}
self.result.push(Suggestion::new_with_tooltip(
StringRange::between(self.start, self.input.len()),
text,
tooltip,
));
self
}
pub fn suggest_with_value(&mut self, value: i32) -> &mut SuggestionsBuilder {
self.result.push(IntegerSuggestion::new(
StringRange::between(self.start, self.input.len()),
value,
));
self
}
pub fn suggest_with_value_and_tooltip(
&mut self,
value: i32,
tooltip: &str,
) -> &mut SuggestionsBuilder {
self.result.push(IntegerSuggestion::new_with_tooltip(
StringRange::between(self.start, self.input.len()),
value,
tooltip,
));
self
}
pub fn add(&mut self, other: &SuggestionsBuilder) -> &mut SuggestionsBuilder {
self.result.extend(other.result.iter().cloned());
self
}
pub fn create_offset(&self, start: usize) -> SuggestionsBuilder {
SuggestionsBuilder::new_with_lowercase(
self.input.clone(),
self.input_lowercase.clone(),
start,
)
}
pub fn restart(&self) -> SuggestionsBuilder {
self.create_offset(self.start)
}
}

View file

@ -1,13 +1,14 @@
use std::fmt::{Display, Formatter};
use crate::{
arguments::argument_type::ArgumentType,
arguments::argument_type::{ArgumentType, Types},
builder::required_argument_builder::RequiredArgumentBuilder,
context::{
command_context::CommandContext, command_context_builder::CommandContextBuilder,
parsed_argument::ParsedArgument,
},
exceptions::command_syntax_exception::CommandSyntaxException,
immutable_string_reader::ImmutableStringReader,
string_reader::StringReader,
suggestion::{
suggestion_provider::SuggestionProvider, suggestions::Suggestions,
@ -20,11 +21,15 @@ use super::command_node::{BaseCommandNode, CommandNode};
const USAGE_ARGUMENT_OPEN: &str = "<";
const USAGE_ARGUMENT_CLOSE: &str = ">";
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
pub struct ArgumentCommandNode<'a, S, T> {
pub struct ArgumentCommandNode<'a, S, T>
where
// each argument command node has its own different type
T: ArgumentType<dyn Types>,
{
name: String,
type_: &'a T,
custom_suggestions: &'a dyn SuggestionProvider<S, T>,
custom_suggestions: Option<&'a dyn SuggestionProvider<S, T>>,
// custom_suggestions: &'a dyn SuggestionProvider<S, T>,
// Since Rust doesn't have extending, we put the struct this is extending as the "base" field
pub base: BaseCommandNode<'a, S, T>,
}
@ -34,12 +39,12 @@ impl<S, T> ArgumentCommandNode<'_, S, T> {
&self.type_
}
fn custom_suggestions(&self) -> &dyn SuggestionProvider<S, T> {
&self.custom_suggestions
fn custom_suggestions(&self) -> Option<&dyn SuggestionProvider<S, T>> {
self.custom_suggestions
}
}
impl<S, T> CommandNode<S, T> for ArgumentCommandNode<'_, S, T> {
impl<'a, S, T> CommandNode<S, T> for ArgumentCommandNode<'a, S, T> {
fn name(&self) -> &str {
&self.name
}
@ -56,7 +61,7 @@ impl<S, T> CommandNode<S, T> for ArgumentCommandNode<'_, S, T> {
// contextBuilder.withArgument(name, parsed);
// contextBuilder.withNode(this, parsed.getRange());
let start = reader.get_cursor();
let start = reader.cursor();
let result = self.get_type().parse(reader)?;
let parsed = ParsedArgument::new(start, reader.get_cursor(), result);
@ -112,7 +117,7 @@ impl<S, T> CommandNode<S, T> for ArgumentCommandNode<'_, S, T> {
}
}
impl Display for ArgumentCommandNode<'_, String, String> {
impl Display for ArgumentCommandNode<'_, (), (), ()> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "<argument {}: {}>", self.name, self.type_)
}

View file

@ -31,7 +31,7 @@ pub trait CommandNode<S, T> {
fn usage_text(&self) -> &str;
fn parse(
&self,
reader: StringReader,
reader: &mut StringReader,
context_builder: CommandContextBuilder<S, T>,
) -> Result<(), CommandSyntaxException>;
fn list_suggestions(

View file

@ -11,7 +11,6 @@ use crate::{
use super::command_node::{BaseCommandNode, CommandNode};
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
pub struct RootCommandNode<'a, S, T> {
// Since Rust doesn't have extending, we put the struct this is extending as the "base" field
pub base: BaseCommandNode<'a, S, T>,