mcproto_types/debug/event.rs
1//! Debug subscription events.
2
3use std::io::{Read, Write};
4
5use mcproto_codec::error::{CodecError, CodecKind};
6
7use crate::TypeCodec;
8
9use super::{DebugSubscriptionData, DebugSubscriptionType};
10
11/// A typed debug subscription event.
12///
13/// The wire representation is a VarInt [`DebugSubscriptionType`] followed by
14/// the payload selected by that type. The discriminator is derived from
15/// [`data`](Self::data), so an event cannot contain mismatched type and data.
16///
17/// # Examples
18///
19/// ```
20/// use mcproto_types::{
21/// DebugSubscriptionData, DebugSubscriptionEvent, EntityBlockIntersectionDebugData,
22/// EntityBlockIntersectionState, TypeCodec,
23/// };
24///
25/// let event = DebugSubscriptionEvent::new(
26/// DebugSubscriptionData::EntityBlockIntersection(
27/// EntityBlockIntersectionDebugData {
28/// state: EntityBlockIntersectionState::InFluid,
29/// },
30/// ),
31/// );
32/// let mut encoded = Vec::new();
33/// event.encode(&mut encoded)?;
34/// assert_eq!(encoded, [0x06, 0x01]);
35/// assert_eq!(DebugSubscriptionEvent::decode(&mut encoded.as_slice())?, event);
36/// # Ok::<(), mcproto_codec::error::CodecError>(())
37/// ```
38///
39/// See the official [Debug Subscription Event] documentation.
40///
41/// [Debug Subscription Event]: https://minecraft.wiki/w/Java_Edition_protocol/Packets#Debug_Subscription_Event
42#[derive(Debug, Clone, PartialEq)]
43pub struct DebugSubscriptionEvent {
44 /// Payload and its associated subscription type.
45 pub data: DebugSubscriptionData,
46}
47
48impl DebugSubscriptionEvent {
49 /// Creates an event from a typed payload.
50 #[must_use]
51 pub const fn new(data: DebugSubscriptionData) -> Self {
52 Self { data }
53 }
54
55 /// Returns the discriminator associated with this event.
56 #[must_use]
57 pub const fn subscription_type(&self) -> DebugSubscriptionType {
58 self.data.subscription_type()
59 }
60}
61
62impl From<DebugSubscriptionData> for DebugSubscriptionEvent {
63 fn from(data: DebugSubscriptionData) -> Self {
64 Self::new(data)
65 }
66}
67
68impl TypeCodec for DebugSubscriptionEvent {
69 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
70 self.subscription_type()
71 .encode(writer)
72 .map_err(|error| error.with_context(CodecKind::DebugSubscriptionEvent))?;
73 self.data
74 .encode_payload(writer)
75 .map_err(|error| error.with_context(CodecKind::DebugSubscriptionEvent))
76 }
77
78 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
79 let subscription_type = DebugSubscriptionType::decode(reader)
80 .map_err(|error| error.with_context(CodecKind::DebugSubscriptionEvent))?;
81 DebugSubscriptionData::decode_payload(subscription_type, reader)
82 .map(Self::new)
83 .map_err(|error| error.with_context(CodecKind::DebugSubscriptionEvent))
84 }
85}