aboutsummaryrefslogtreecommitdiff
path: root/azalea-brigadier/src/suggestion
diff options
context:
space:
mode:
authorEightFactorial <murphkev000@gmail.com>2022-12-06 18:48:48 -0800
committerGitHub <noreply@github.com>2022-12-06 20:48:48 -0600
commit9f5e5c092be9167e4d5222fdee4a1d2c419e5052 (patch)
tree1d0a8b57434e0afd14b4a02cbbc579a3ad70da61 /azalea-brigadier/src/suggestion
parente99a822995c80e1f95c5f7a69e0d8c5d131af20f (diff)
downloadazalea-drasl-9f5e5c092be9167e4d5222fdee4a1d2c419e5052.tar.xz
Complete ClientboundCommand{Suggestion}sPacket, Serde support for NBT Tags (#49)
* Serializing ClientboundStatusResponsePacket Enable serialization of ClientboundStatusResponsePacket * Update clientbound_status_response_packet.rs Add options previewsChat and enforcesSecureChat * Serialize Style and TextColor * Serialize BaseComponent * Serialize TextComponent * Fix Style * Serialize Component * Fix multiple formats per message, fix reset tag * Fix Style, again * Use FlatMapSerializer * Forgot italics * Count struct fields, reorganize logic * Serialize TranslatableComponent * Rewrite TextComponent Serializer * Fix using TextColor::Parse * Code Cleanup * Add default attribute, just in case * Clippy * use serde derive feature + preferred formatting choices * McBufWritable for BrigadierNodeStub * Thanks Clippy... * Implement suggestions in azalea-brigadier * Serde support for NBT Tags * Serde options * Forgot Options * Oops, that's McBufWritable for BrigadierParser * Fix McBufWritable for SlotData * Complete ClientboundUpdateRecipesPacket * fix some issues * better impl McBufReadable for Suggestions Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: mat <github@matdoes.dev>
Diffstat (limited to 'azalea-brigadier/src/suggestion')
-rwxr-xr-xazalea-brigadier/src/suggestion/mod.rs31
-rwxr-xr-xazalea-brigadier/src/suggestion/suggestions.rs74
2 files changed, 91 insertions, 14 deletions
diff --git a/azalea-brigadier/src/suggestion/mod.rs b/azalea-brigadier/src/suggestion/mod.rs
index 4c9a9547..114a4c47 100755
--- a/azalea-brigadier/src/suggestion/mod.rs
+++ b/azalea-brigadier/src/suggestion/mod.rs
@@ -1,16 +1,26 @@
mod suggestions;
-use crate::{context::StringRange, message::Message};
+use crate::context::StringRange;
+#[cfg(feature = "azalea-buf")]
+use azalea_buf::McBufWritable;
+#[cfg(feature = "azalea-buf")]
+use azalea_chat::Component;
+#[cfg(feature = "azalea-buf")]
+use std::io::Write;
pub use suggestions::*;
+/// A suggestion given to the user for what they might want to type next.
+///
+/// The `M` generic is the type of the tooltip, so for example a `String` or
+/// just `()` if you don't care about it.
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
-pub struct Suggestion {
- pub range: StringRange,
+pub struct Suggestion<M = String> {
pub text: String,
- pub tooltip: Option<Message>,
+ pub range: StringRange,
+ pub tooltip: Option<M>,
}
-impl Suggestion {
+impl<M: Clone> Suggestion<M> {
pub fn apply(&self, input: &str) -> String {
if self.range.start() == 0 && self.range.end() == input.len() {
return input.to_string();
@@ -27,7 +37,7 @@ impl Suggestion {
result
}
- pub fn expand(&self, command: &str, range: &StringRange) -> Suggestion {
+ pub fn expand(&self, command: &str, range: &StringRange) -> Suggestion<M> {
if range == &self.range {
return self.clone();
}
@@ -46,3 +56,12 @@ impl Suggestion {
}
}
}
+
+#[cfg(feature = "azalea-buf")]
+impl McBufWritable for Suggestion<Component> {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ self.text.write_into(buf)?;
+ self.tooltip.write_into(buf)?;
+ Ok(())
+ }
+}
diff --git a/azalea-brigadier/src/suggestion/suggestions.rs b/azalea-brigadier/src/suggestion/suggestions.rs
index 1fe361f1..06ef9661 100755
--- a/azalea-brigadier/src/suggestion/suggestions.rs
+++ b/azalea-brigadier/src/suggestion/suggestions.rs
@@ -1,15 +1,23 @@
use super::Suggestion;
use crate::context::StringRange;
-use std::collections::HashSet;
+#[cfg(feature = "azalea-buf")]
+use azalea_buf::{
+ BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
+};
+#[cfg(feature = "azalea-buf")]
+use azalea_chat::Component;
+#[cfg(feature = "azalea-buf")]
+use std::io::{Cursor, Write};
+use std::{collections::HashSet, hash::Hash};
-#[derive(Debug, Clone, Default, Eq, PartialEq, Hash)]
-pub struct Suggestions {
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
+pub struct Suggestions<M = String> {
pub range: StringRange,
- pub suggestions: Vec<Suggestion>,
+ pub suggestions: Vec<Suggestion<M>>,
}
-impl Suggestions {
- pub fn merge(command: &str, input: &[Suggestions]) -> Self {
+impl<M: Clone + Eq + Hash> Suggestions<M> {
+ pub fn merge(command: &str, input: &[Suggestions<M>]) -> Self {
if input.is_empty() {
return Suggestions::default();
} else if input.len() == 1 {
@@ -24,7 +32,7 @@ impl Suggestions {
Suggestions::create(command, &texts)
}
- pub fn create(command: &str, suggestions: &HashSet<Suggestion>) -> Self {
+ pub fn create(command: &str, suggestions: &HashSet<Suggestion<M>>) -> Self {
if suggestions.is_empty() {
return Suggestions::default();
};
@@ -39,7 +47,7 @@ impl Suggestions {
for suggestion in suggestions {
texts.insert(suggestion.expand(command, &range));
}
- let mut sorted: Vec<Suggestion> = texts.into_iter().collect();
+ let mut sorted = texts.into_iter().collect::<Vec<_>>();
sorted.sort_by(|a, b| a.text.cmp(&b.text));
Suggestions {
range,
@@ -47,3 +55,53 @@ impl Suggestions {
}
}
}
+
+// this can't be derived because that'd require the generic to have `Default`
+// too even if it's not actually necessary
+impl<M> Default for Suggestions<M> {
+ fn default() -> Self {
+ Self {
+ range: StringRange::default(),
+ suggestions: Vec::new(),
+ }
+ }
+}
+
+#[cfg(feature = "azalea-buf")]
+impl McBufReadable for Suggestions<Component> {
+ fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
+ #[derive(McBuf)]
+ struct StandaloneSuggestion {
+ pub text: String,
+ pub tooltip: Option<Component>,
+ }
+
+ let start = u32::var_read_from(buf)? as usize;
+ let length = u32::var_read_from(buf)? as usize;
+ let range = StringRange::between(start, start + length);
+
+ // the range of a Suggestion depends on the Suggestions containing it,
+ // so we can't just `impl McBufReadable for Suggestion`
+ let mut suggestions = Vec::<StandaloneSuggestion>::read_from(buf)?
+ .into_iter()
+ .map(|s| Suggestion {
+ text: s.text,
+ tooltip: s.tooltip,
+ range: range.clone(),
+ })
+ .collect::<Vec<_>>();
+ suggestions.sort_by(|a, b| a.text.cmp(&b.text));
+
+ Ok(Suggestions { range, suggestions })
+ }
+}
+
+#[cfg(feature = "azalea-buf")]
+impl McBufWritable for Suggestions<Component> {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ (self.range.start() as u32).var_write_into(buf)?;
+ (self.range.length() as u32).var_write_into(buf)?;
+ self.suggestions.write_into(buf)?;
+ Ok(())
+ }
+}