aboutsummaryrefslogtreecommitdiff
path: root/src/protocol.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/protocol.rs')
-rw-r--r--src/protocol.rs143
1 files changed, 58 insertions, 85 deletions
diff --git a/src/protocol.rs b/src/protocol.rs
index 7a13175..1e89987 100644
--- a/src/protocol.rs
+++ b/src/protocol.rs
@@ -87,16 +87,31 @@ pub struct ProtocolPacketField {
pub kind: String,
}
-pub trait Packet: Sized {
+pub trait HasPacketId {
+
fn id(&self) -> Id;
fn version() -> crate::types::VarInt;
+}
- fn mc_deserialize(raw: RawPacket<'_>) -> Result<Self, PacketErr>;
+pub trait HasPacketBody {
fn mc_serialize_body<S>(&self, to: &mut S) -> SerializeResult where S: Serializer;
}
+pub trait RawPacket<'a>: HasPacketId + Sized {
+
+ type Packet: Packet;
+
+ fn create(id: Id, data: &'a [u8]) -> Result<Self, PacketErr>;
+
+ fn data(&self) -> &'a [u8];
+
+ fn deserialize(&self) -> Result<Self::Packet, PacketErr>;
+}
+
+pub trait Packet: HasPacketId + HasPacketBody + Sized {}
+
pub enum PacketErr {
UnknownId(Id),
DeserializeFailed(DeserializeErr),
@@ -128,12 +143,6 @@ impl fmt::Debug for PacketErr {
#[cfg(feature = "std")]
impl std::error::Error for PacketErr {}
-#[derive(Debug, Clone, PartialEq)]
-pub struct RawPacket<'a> {
- pub id: Id,
- pub data: &'a [u8],
-}
-
pub trait ProtocolType: Serialize + Deserialize {}
impl<T: Serialize + Deserialize> ProtocolType for T {}
@@ -247,7 +256,7 @@ macro_rules! define_protocol {
}
}
- impl crate::protocol::Packet for $packett {
+ impl crate::protocol::HasPacketId for $packett {
fn version() -> crate::types::VarInt {
crate::types::VarInt($version)
}
@@ -261,32 +270,9 @@ macro_rules! define_protocol {
$($nam(_) => ($id, $state, $direction)),*
}.into()
}
+ }
- fn mc_deserialize(raw: crate::protocol::RawPacket) ->
- Result<Self, crate::protocol::PacketErr>
- {
- use self::$packett::*;
- use crate::protocol::State::*;
- use crate::protocol::PacketDirection::*;
- use crate::protocol::PacketErr::*;
- use crate::{Deserialize, Deserialized};
-
- let id = raw.id;
- let data = raw.data;
-
- match (id.id, id.state, id.direction) {
- $(($id, $state, $direction) => {
- let Deserialized { value: body, data: rest } = $body::mc_deserialize(data).map_err(DeserializeFailed)?;
- if !rest.is_empty() {
- Err(ExtraData(rest.to_vec()))
- } else {
- Ok($nam(body))
- }
- }),*,
- other => Err(UnknownId(other.into())),
- }
- }
-
+ impl crate::protocol::HasPacketBody for $packett {
fn mc_serialize_body<S>(&self, to: &mut S) -> crate::SerializeResult where S: crate::Serializer {
use self::$packett::*;
match self {
@@ -295,6 +281,8 @@ macro_rules! define_protocol {
}
}
+ impl crate::protocol::Packet for $packett {}
+
impl $packett {
pub fn describe() -> crate::protocol::ProtocolSpec {
crate::protocol::ProtocolSpec {
@@ -318,80 +306,65 @@ macro_rules! define_protocol {
}
}
- #[cfg(feature = "std")]
- impl<'a> std::convert::TryFrom<crate::protocol::RawPacket<'a>> for $rawpackett<'a> {
- type Error = crate::protocol::PacketErr;
-
- fn try_from(value: crate::protocol::RawPacket<'a>) -> Result<Self, Self::Error> {
+ impl<'a> crate::protocol::HasPacketId for $rawpackett<'a> {
+ fn id(&self) -> crate::protocol::Id {
use self::$rawpackett::*;
use crate::protocol::State::*;
use crate::protocol::PacketDirection::*;
- use crate::protocol::PacketErr::*;
- #[cfg(feature = "std")]
- use std::marker;
- #[cfg(not(feature = "std"))]
- use no_std_compat::marker;
-
- match (value.id.id, value.id.state, value.id.direction) {
- $(($id, $state, $direction) => Ok($nam($rawdt {
- data: value.data,
- _typ: marker::PhantomData,
- }))),*,
- other => Err(UnknownId(other.into()))
- }
- }
- }
- #[cfg(feature = "std")]
- impl<'a> std::convert::Into<crate::protocol::RawPacket<'a>> for $rawpackett<'a> {
- fn into(self) -> crate::protocol::RawPacket<'a> {
- self.into_raw_packet()
+ match self {
+ $($nam(_) => ($id, $state, $direction)),*
+ }.into()
}
- }
- impl<'a> $rawpackett<'a> {
- fn into_raw_packet(self) -> crate::protocol::RawPacket<'a> {
- crate::protocol::RawPacket {
- id: self.id(),
- data: self.bytes(),
- }
+ fn version() -> crate::types::VarInt {
+ crate::types::VarInt($version)
}
}
- #[cfg(feature = "std")]
- impl<'a> std::convert::Into<&'a [u8]> for $rawpackett<'a> {
- fn into(self) -> &'a [u8] {
- use self::$rawpackett::*;
+ impl<'a> crate::protocol::RawPacket<'a> for $rawpackett<'a> {
- match self {
- $($nam(bod) => bod.data),*
- }
- }
- }
+ type Packet = $packett;
- impl<'a> $rawpackett<'a> {
- pub fn id(&self) -> crate::protocol::Id {
+ fn create(id: crate::protocol::Id, data: &'a[u8]) -> Result<Self, crate::protocol::PacketErr> {
use self::$rawpackett::*;
use crate::protocol::State::*;
use crate::protocol::PacketDirection::*;
+ use crate::protocol::PacketErr::UnknownId;
- match self {
- $($nam(_) => ($id, $state, $direction)),*
- }.into()
- }
-
- pub fn deserialize(self) -> Result<$packett, crate::protocol::PacketErr> {
- use crate::protocol::Packet;
- $packett::mc_deserialize(self.into_raw_packet())
+ match (id.id, id.state, id.direction) {
+ $(($id, $state, $direction) => Ok($nam($rawdt{
+ data,
+ _typ: core::marker::PhantomData,
+ }))),*,
+ other => Err(UnknownId(other.into()))
+ }
}
- pub fn bytes(&self) -> &'a [u8] {
+ fn data(&self) -> &'a [u8] {
use self::$rawpackett::*;
match self {
$($nam(bod) => bod.data),*
}
}
+
+ fn deserialize(&self) -> Result<Self::Packet, crate::protocol::PacketErr> {
+ use crate::protocol::PacketErr::{ExtraData, DeserializeFailed};
+
+ match self {
+ $($rawpackett::$nam(bod) => {
+ let Deserialized { value: body, data: rest } =
+ $body::mc_deserialize(bod.data)
+ .map_err(move |err| DeserializeFailed(err))?;
+ if !rest.is_empty() {
+ Err(ExtraData(rest.to_vec()))
+ } else {
+ Ok($packett::$nam(body))
+ }
+ }),*,
+ }
+ }
}
#[derive(PartialEq, Debug)]