aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-10-01 19:12:27 -0500
committermat <git@matdoes.dev>2023-10-01 19:12:27 -0500
commit2606de9f4c1563c10a616925a87905ea1ffd2298 (patch)
tree0bfe20e49c6b2ffc22076b3e63e26a0afb08c27a
parent8b65d7c95e9bc4290ff1a6f5ae1de6fc71ef03d4 (diff)
downloadazalea-drasl-2606de9f4c1563c10a616925a87905ea1ffd2298.tar.xz
start adding brigadier suggestions
-rwxr-xr-xazalea-brigadier/src/suggestion/mod.rs4
-rwxr-xr-xazalea-brigadier/src/suggestion/suggestions_builder.rs92
-rwxr-xr-xazalea-brigadier/tests/suggestion/suggestion_test.rs71
-rwxr-xr-xazalea-brigadier/tests/suggestion/suggestions_test.rs20
4 files changed, 186 insertions, 1 deletions
diff --git a/azalea-brigadier/src/suggestion/mod.rs b/azalea-brigadier/src/suggestion/mod.rs
index 592c674c..22257423 100755
--- a/azalea-brigadier/src/suggestion/mod.rs
+++ b/azalea-brigadier/src/suggestion/mod.rs
@@ -1,4 +1,5 @@
mod suggestions;
+ mod suggestions_builder;
use crate::context::StringRange;
#[cfg(feature = "azalea-buf")]
@@ -7,7 +8,8 @@ use azalea_buf::McBufWritable;
use azalea_chat::FormattedText;
#[cfg(feature = "azalea-buf")]
use std::io::Write;
-pub use suggestions::*;
+pub use suggestions::Suggestions;
+pub use suggestions_builder::SuggestionsBuilder;
/// A suggestion given to the user for what they might want to type next.
///
diff --git a/azalea-brigadier/src/suggestion/suggestions_builder.rs b/azalea-brigadier/src/suggestion/suggestions_builder.rs
new file mode 100755
index 00000000..66f17fb1
--- /dev/null
+++ b/azalea-brigadier/src/suggestion/suggestions_builder.rs
@@ -0,0 +1,92 @@
+use std::collections::HashSet;
+
+use crate::context::StringRange;
+
+use super::{Suggestion, Suggestions};
+
+pub struct SuggestionsBuilder {
+ input: String,
+ input_lowercase: String,
+ start: usize,
+ remaining: String,
+ remaining_lowercase: String,
+ result: HashSet<Suggestion>,
+}
+
+impl SuggestionsBuilder {
+ pub fn new(input: &str, start: usize) -> Self {
+ Self::new_with_lowercase(input, input.to_lowercase().as_str(), start)
+ }
+
+ pub fn new_with_lowercase(input: &str, input_lowercase: &str, start: usize) -> Self {
+ Self {
+ start,
+ input: input.to_string(),
+ input_lowercase: input_lowercase.to_string(),
+ remaining: input[start..].to_string(),
+ remaining_lowercase: input_lowercase[start..].to_string(),
+ result: HashSet::new(),
+ }
+ }
+
+ pub fn input(&self) -> &str {
+ &self.input
+ }
+
+ pub fn start(&self) -> usize {
+ self.start
+ }
+
+ pub fn remianing(&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) -> Self {
+ if text == self.remaining {
+ return self;
+ }
+ self.result.insert(Suggestion {
+ range: StringRange::between(self.start, self.input.len()),
+ text: text.to_string(),
+ tooltip: None,
+ });
+ self
+ }
+
+ pub fn suggest_with_tooltip(mut self, text: &str, tooltip: String) -> Self {
+ if text == self.remaining {
+ return self;
+ }
+ self.result.insert(Suggestion {
+ range: StringRange::between(self.start, self.input.len()),
+ text: text.to_string(),
+ tooltip: Some(tooltip),
+ });
+ self
+ }
+
+ // TODO: integer suggestions
+ // https://github.com/Mojang/brigadier/blob/master/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java#L74
+
+ #[allow(clippy::should_implement_trait)]
+ pub fn add(mut self, other: SuggestionsBuilder) -> Self {
+ self.result.extend(other.result);
+ self
+ }
+
+ pub fn create_offset(&self, start: usize) -> Self {
+ SuggestionsBuilder::new_with_lowercase(&self.input, &self.input_lowercase, start)
+ }
+
+ pub fn restart(self) -> Self {
+ self.create_offset(self.start)
+ }
+}
diff --git a/azalea-brigadier/tests/suggestion/suggestion_test.rs b/azalea-brigadier/tests/suggestion/suggestion_test.rs
index e69de29b..9ba95807 100755
--- a/azalea-brigadier/tests/suggestion/suggestion_test.rs
+++ b/azalea-brigadier/tests/suggestion/suggestion_test.rs
@@ -0,0 +1,71 @@
+#[test]
+fn apply_insertation_start() {
+ let suggestion = Suggestion::new(StringRange::at(0), "And so I said: ");
+ assert_eq!(suggestion.apply("Hello world!"), "And so I said: Hello world!");
+}
+
+#[test]
+fn apply_insertation_middle() {
+ let suggestion = Suggestion::new(StringRange::at(6), "small ");
+ assert_eq!(suggestion.apply("Hello world!"), "Hello small world!");
+}
+
+#[test]
+fn apply_insertation_end() {
+ let suggestion = Suggestion::new(StringRange::at(5), " world!");
+ assert_eq!(suggestion.apply("Hello"), "Hello world!");
+}
+
+#[test]
+fn apply_replacement_start() {
+ let suggestion = Suggestion::new(StringRange::between(0, 5), "Goodbye");
+ assert_eq!(suggestion.apply("Hello world!"), "Goodbye world!");
+}
+
+#[test]
+fn apply_replacement_middle() {
+ let suggestion = Suggestion::new(StringRange::between(6, 11), "Alex");
+ assert_eq!(suggestion.apply("Hello world!"), "Hello Alex!");
+}
+
+#[test]
+fn apply_replacement_end() {
+ let suggestion = Suggestion::new(StringRange::between(6, 12), "Creeper!");
+ assert_eq!(suggestion.apply("Hello world!"), "Hello Creeper!");
+}
+
+#[test]
+fn apply_replacement_everything() {
+ let suggestion = Suggestion::new(StringRange::between(0, 12), "Oh dear.");
+ assert_eq!(suggestion.apply("Hello world!"), "Oh dear.");
+}
+
+#[test]
+fn expand_unchanged() {
+ let suggestion = Suggestion::new(StringRange::at(1), "oo");
+ assert_eq!(suggestion.expand("f", StringRange::at(1)), suggestion);
+}
+
+#[test]
+fn expand_left() {
+ let suggestion = Suggestion::new(StringRange::at(1), "oo");
+ assert_eq!(suggestion.expand("f", StringRange::between(0, 1)), Suggestion::new(StringRange::between(0, 1), "foo"));
+}
+
+#[test]
+fn expand_right() {
+ let suggestion = Suggestion::new(StringRange::at(0), "minecraft:");
+ assert_eq!(suggestion.expand("fish", StringRange::between(0, 4)), Suggestion::new(StringRange::between(0, 4), "minecraft:fish"));
+}
+
+#[test]
+fn expand_both() {
+ let suggestion = Suggestion::new(StringRange::at(11), "minecraft:");
+ assert_eq!(suggestion.expand("give Steve fish_block", StringRange::between(5, 21)), Suggestion::new(StringRange::between(5, 21), "Steve minecraft:fish_block"));
+}
+
+#[test]
+fn expand_replacement() {
+ let suggestion = Suggestion::new(StringRange::between(6, 11), "strangers");
+ assert_eq!(suggestion.expand("Hello world!", StringRange::between(0, 12)), Suggestion::new(StringRange::between(0, 12), "Hello strangers!"));
+} \ No newline at end of file
diff --git a/azalea-brigadier/tests/suggestion/suggestions_test.rs b/azalea-brigadier/tests/suggestion/suggestions_test.rs
index e69de29b..28a8266d 100755
--- a/azalea-brigadier/tests/suggestion/suggestions_test.rs
+++ b/azalea-brigadier/tests/suggestion/suggestions_test.rs
@@ -0,0 +1,20 @@
+#[test]
+fn merge_empty() {
+ let merged = Suggestions::merge("foo b", vec![]);
+ assert!(merged.is_empty());
+}
+
+#[test]
+fn merge_single() {
+ let suggestions = Suggestions::new(StringRange::at(5), vec![Suggestion::new(StringRange::at(5), "ar")]);
+ 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"), Suggestion::new(StringRange::at(5), "az"), Suggestion::new(StringRange::at(5), "Az")]);
+ let b = Suggestions::new(StringRange::between(4, 5), vec![Suggestion::new(StringRange::between(4, 5), "foo"), Suggestion::new(StringRange::between(4, 5), "qux"), Suggestion::new(StringRange::between(4, 5), "apple"), Suggestion::new(StringRange::between(4, 5), "Bar")]);
+ let merged = Suggestions::merge("foo b", vec![a, b]);
+ assert_eq!(merged.get_list(), vec![Suggestion::new(StringRange::between(4, 5), "apple"), Suggestion::new(StringRange::between(4, 5), "ar"), Suggestion::new(StringRange::between(4, 5), "Az"), Suggestion::new(StringRange::between(4, 5), "bar"), Suggestion::new(StringRange::between(4, 5), "Bar"), Suggestion::new(StringRange::between(4, 5), "baz"), Suggestion::new(StringRange::between(4, 5), "bAz"), Suggestion::new(StringRange::between(4, 5), "foo"), Suggestion::new(StringRange::between(4, 5), "qux")]);
+} \ No newline at end of file