use std::io::{Read, Write};
use mcproto_codec::error::{CodecError, CodecKind};
use crate::{Boolean, TypeCodec};
use super::{DebugSubscriptionData, DebugSubscriptionType};
#[derive(Debug, Clone, PartialEq)]
pub enum DebugSubscriptionUpdate {
Absent(DebugSubscriptionType),
Present(DebugSubscriptionData),
}
impl DebugSubscriptionUpdate {
#[must_use]
pub const fn absent(subscription_type: DebugSubscriptionType) -> Self {
Self::Absent(subscription_type)
}
#[must_use]
pub const fn present(data: DebugSubscriptionData) -> Self {
Self::Present(data)
}
#[must_use]
pub const fn subscription_type(&self) -> DebugSubscriptionType {
match self {
Self::Absent(subscription_type) => *subscription_type,
Self::Present(data) => data.subscription_type(),
}
}
#[must_use]
pub const fn data(&self) -> Option<&DebugSubscriptionData> {
match self {
Self::Absent(_) => None,
Self::Present(data) => Some(data),
}
}
#[must_use]
pub const fn is_present(&self) -> bool {
matches!(self, Self::Present(_))
}
}
impl TypeCodec for DebugSubscriptionUpdate {
fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
self.subscription_type()
.encode(writer)
.map_err(|error| error.with_context(CodecKind::DebugSubscriptionUpdate))?;
let data = self.data();
Boolean(data.is_some())
.encode(writer)
.map_err(|error| error.with_context(CodecKind::DebugSubscriptionUpdate))?;
if let Some(data) = data {
data.encode_payload(writer)
.map_err(|error| error.with_context(CodecKind::DebugSubscriptionUpdate))?;
}
Ok(())
}
fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
let subscription_type = DebugSubscriptionType::decode(reader)
.map_err(|error| error.with_context(CodecKind::DebugSubscriptionUpdate))?;
let present = Boolean::decode(reader)
.map_err(|error| error.with_context(CodecKind::DebugSubscriptionUpdate))?;
if present.0 {
DebugSubscriptionData::decode_payload(subscription_type, reader)
.map(Self::Present)
.map_err(|error| error.with_context(CodecKind::DebugSubscriptionUpdate))
} else {
Ok(Self::Absent(subscription_type))
}
}
}