aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/chat.rs116
-rw-r--r--src/types.rs62
-rw-r--r--src/v1_15_2.rs47
-rw-r--r--src/v1_16_3.rs47
4 files changed, 112 insertions, 160 deletions
diff --git a/src/chat.rs b/src/chat.rs
index 77087da..550c9ce 100644
--- a/src/chat.rs
+++ b/src/chat.rs
@@ -76,7 +76,7 @@ struct TraditionalParser {
impl TraditionalParser {
- fn new(source: &str, translate_colorcodes: bool) -> TraditionalParser {
+ fn new(source: &str, translate_colorcodes: bool) -> Self {
Self {
source: source.chars().collect(),
at: 0,
@@ -510,50 +510,25 @@ impl<'de> Deserialize<'de> for ChatClickEvent {
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, <A as MapAccess<'de>>::Error> where
A: MapAccess<'de>
{
- let mut action: Option<&str> = None;
- let mut value: Option<Value> = None;
- while action.is_none() || value.is_none() {
- if let Some(key) = map.next_key()? {
- match key {
- "action" => {
- action = map.next_value()?;
- if action.is_none() {
- return Err(A::Error::custom("none for value key=action"));
- }
- },
- "value" => {
- value = map.next_value()?;
- if value.is_none() {
- return Err(A::Error::custom("none for value key=value"));
- }
- },
- other => {
- return Err(A::Error::custom(format!("unexpected key in event {}", other)));
- }
- }
- } else {
- return Err(A::Error::custom(format!("event needs action and value")));
- }
- }
+ let (action, value) = read_event(&mut map)?;
use ChatClickEvent::*;
- let v = value.expect("set this in while loop");
- match action.expect("set this in while loop") {
- "open_url" => match v.as_str() {
+ match action {
+ "open_url" => match value.as_str() {
Some(url) => Ok(OpenUrl(url.to_owned())),
- None => Err(A::Error::custom(format!("open_url requires string body, got {}", v)))
+ None => Err(A::Error::custom(format!("open_url requires string body, got {}", value)))
},
- "run_command" => match v.as_str() {
+ "run_command" => match value.as_str() {
Some(cmd) => Ok(RunCommand(cmd.to_owned())),
- None => Err(A::Error::custom(format!("run_command requires string body, got {}", v)))
+ None => Err(A::Error::custom(format!("run_command requires string body, got {}", value)))
},
- "suggest_command" => match v.as_str() {
+ "suggest_command" => match value.as_str() {
Some(cmd) => Ok(SuggestCommand(cmd.to_owned())),
- None => Err(A::Error::custom(format!("suggest_command requires string body, got {}", v)))
+ None => Err(A::Error::custom(format!("suggest_command requires string body, got {}", value)))
},
- "change_page" => match v.as_i64() {
+ "change_page" => match value.as_i64() {
Some(v) => Ok(ChangePage(v as i32)),
- None => Err(A::Error::custom(format!("change_page requires integer body, got {}", v)))
+ None => Err(A::Error::custom(format!("change_page requires integer body, got {}", value)))
},
other => Err(A::Error::custom(format!("invalid click action kind {}", other)))
}
@@ -614,42 +589,17 @@ impl<'de> Deserialize<'de> for ChatHoverEvent {
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, <A as MapAccess<'de>>::Error> where
A: MapAccess<'de>
{
- let mut action: Option<&str> = None;
- let mut value: Option<Value> = None;
- while action.is_none() || value.is_none() {
- if let Some(key) = map.next_key()? {
- match key {
- "action" => {
- action = map.next_value()?;
- if action.is_none() {
- return Err(A::Error::custom("none for value key=action"));
- }
- },
- "value" => {
- value = map.next_value()?;
- if value.is_none() {
- return Err(A::Error::custom("none for value key=value"));
- }
- },
- other => {
- return Err(A::Error::custom(format!("unexpected key in event {}", other)));
- }
- }
- } else {
- return Err(A::Error::custom(format!("event needs action and value")));
- }
- }
+ let (action, value) = read_event(&mut map)?;
use ChatHoverEvent::*;
- let v = value.expect("set this in while loop");
- match action.expect("set this in while loop") {
+ match action {
"show_text" => Ok(ShowText(
- Chat::deserialize(v.into_deserializer())
+ Chat::deserialize(value.into_deserializer())
.map_err(move |err| A::Error::custom(
format!("error deserializing text to show {:?}", err)))?
.boxed())),
- "show_item" => Ok(ShowItem(v)),
- "show_entity" => Ok(ShowEntity(v)),
+ "show_item" => Ok(ShowItem(value)),
+ "show_entity" => Ok(ShowEntity(value)),
other => Err(A::Error::custom(format!("invalid hover action kind {}", other)))
}
}
@@ -1040,6 +990,40 @@ impl TestRandom for Chat {
}
}
+fn read_event<'de, A>(
+ access: &mut A,
+) -> Result<(&'de str, Value), <A as MapAccess<'de>>::Error>
+ where A: MapAccess<'de>
+{
+ let mut action: Option<&str> = None;
+ let mut value: Option<Value> = None;
+ while action.is_none() || value.is_none() {
+ if let Some(key) = access.next_key()? {
+ match key {
+ "action" => {
+ action = access.next_value()?;
+ if action.is_none() {
+ return Err(A::Error::custom("none for value key=action"));
+ }
+ },
+ "value" => {
+ value = access.next_value()?;
+ if value.is_none() {
+ return Err(A::Error::custom("none for value key=value"));
+ }
+ },
+ other => {
+ return Err(A::Error::custom(format!("unexpected key in event {}", other)));
+ }
+ }
+ } else {
+ return Err(A::Error::custom(format!("event needs action and value")));
+ }
+ }
+
+ Ok((action.expect("checked"), value.expect("checked")))
+}
+
#[cfg(test)]
pub mod tests {
diff --git a/src/types.rs b/src/types.rs
index f9b37e1..3a96b22 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -10,6 +10,7 @@ pub use super::chat::*;
#[cfg(all(test, feature = "std"))]
use crate::protocol::TestRandom;
use crate::byte_order::{ProtoByteOrder, ByteOrder};
+use std::ops::Deref;
// bool
impl Serialize for bool {
@@ -838,6 +839,67 @@ impl ArrayCounter for i8 {
}
}
+#[derive(Debug, Clone, PartialEq)]
+pub struct RemainingBytes {
+ pub data: Vec<u8>,
+}
+
+impl Serialize for RemainingBytes {
+ fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
+ to.serialize_bytes(self.data.as_slice())
+ }
+}
+
+impl Deserialize for RemainingBytes {
+ fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
+ Deserialized::ok(
+ RemainingBytes {
+ data: Vec::from(data),
+ },
+ &[],
+ )
+ }
+}
+
+impl Into<Vec<u8>> for RemainingBytes {
+ fn into(self) -> Vec<u8> {
+ self.data
+ }
+}
+
+impl From<Vec<u8>> for RemainingBytes {
+ fn from(data: Vec<u8>) -> Self {
+ Self { data }
+ }
+}
+
+impl core::ops::Deref for RemainingBytes {
+ type Target = Vec<u8>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.data
+ }
+}
+
+impl core::ops::DerefMut for RemainingBytes {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.data
+ }
+}
+
+#[cfg(all(test, feature = "std"))]
+impl TestRandom for RemainingBytes {
+ fn test_gen_random() -> Self {
+ let size: usize = rand::random::<usize>() % 256;
+ let mut out = Vec::with_capacity(size);
+ for _ in 0..size {
+ out.push(rand::random());
+ }
+
+ Self { data: out }
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/src/v1_15_2.rs b/src/v1_15_2.rs
index 1f2f005..402d853 100644
--- a/src/v1_15_2.rs
+++ b/src/v1_15_2.rs
@@ -710,53 +710,6 @@ proto_byte_enum!(HandshakeNextState,
0x02 :: Login
);
-#[derive(Debug, Clone, PartialEq)]
-pub struct RemainingBytes {
- pub data: Vec<u8>,
-}
-
-impl Serialize for RemainingBytes {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- to.serialize_bytes(self.data.as_slice())
- }
-}
-
-impl Deserialize for RemainingBytes {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- Deserialized::ok(
- RemainingBytes {
- data: Vec::from(data),
- },
- &[],
- )
- }
-}
-
-impl Into<Vec<u8>> for RemainingBytes {
- fn into(self) -> Vec<u8> {
- self.data
- }
-}
-
-impl From<Vec<u8>> for RemainingBytes {
- fn from(data: Vec<u8>) -> Self {
- Self { data }
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for RemainingBytes {
- fn test_gen_random() -> Self {
- let size: usize = rand::random::<usize>() % 256;
- let mut out = Vec::with_capacity(size);
- for _ in 0..size {
- out.push(rand::random());
- }
-
- Self { data: out }
- }
-}
-
proto_byte_enum!(CardinalDirection,
0x00 :: South,
0x01 :: West,
diff --git a/src/v1_16_3.rs b/src/v1_16_3.rs
index 7d8643a..3eb5e03 100644
--- a/src/v1_16_3.rs
+++ b/src/v1_16_3.rs
@@ -730,53 +730,6 @@ proto_byte_enum!(HandshakeNextState,
0x02 :: Login
);
-#[derive(Debug, Clone, PartialEq)]
-pub struct RemainingBytes {
- pub data: Vec<u8>,
-}
-
-impl Serialize for RemainingBytes {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- to.serialize_bytes(self.data.as_slice())
- }
-}
-
-impl Deserialize for RemainingBytes {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- Deserialized::ok(
- RemainingBytes {
- data: Vec::from(data),
- },
- &[],
- )
- }
-}
-
-impl Into<Vec<u8>> for RemainingBytes {
- fn into(self) -> Vec<u8> {
- self.data
- }
-}
-
-impl From<Vec<u8>> for RemainingBytes {
- fn from(data: Vec<u8>) -> Self {
- Self { data }
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for RemainingBytes {
- fn test_gen_random() -> Self {
- let size: usize = rand::random::<usize>() % 256;
- let mut out = Vec::with_capacity(size);
- for _ in 0..size {
- out.push(rand::random());
- }
-
- Self { data: out }
- }
-}
-
proto_byte_enum!(CardinalDirection,
0x00 :: South,
0x01 :: West,