Skip to main content

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}