use mcproto_codec::error::{CodecError, CodecKind};
use crate::{
ProtocolEnum, TypeCodec,
basic::{PrefixedString, VarInt},
contextual::PrefixedArray,
nbt::Nbt,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ProtocolEnum)]
#[protocol_enum(repr = VarInt)]
pub enum ChatTypeParameter {
Sender = 0,
Target = 1,
Content = 2,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ChatDecoration {
pub translation_key: PrefixedString,
pub parameters: PrefixedArray<ChatTypeParameter>,
pub style: Nbt,
}
impl ChatDecoration {
#[must_use]
pub const fn new(
translation_key: PrefixedString,
parameters: PrefixedArray<ChatTypeParameter>,
style: Nbt,
) -> Self {
Self {
translation_key,
parameters,
style,
}
}
}
impl TypeCodec for ChatDecoration {
fn encode(&self, writer: &mut impl std::io::Write) -> Result<(), CodecError> {
self.translation_key
.encode(writer)
.map_err(|error| error.with_context(CodecKind::ChatDecoration))?;
self.parameters
.encode(writer)
.map_err(|error| error.with_context(CodecKind::ChatDecoration))?;
self.style
.encode(writer)
.map_err(|error| error.with_context(CodecKind::ChatDecoration))
}
fn decode(reader: &mut impl std::io::Read) -> Result<Self, CodecError> {
let translation_key = PrefixedString::decode(reader)
.map_err(|error| error.with_context(CodecKind::ChatDecoration))?;
let parameters = PrefixedArray::<ChatTypeParameter>::decode(reader)
.map_err(|error| error.with_context(CodecKind::ChatDecoration))?;
let style =
Nbt::decode(reader).map_err(|error| error.with_context(CodecKind::ChatDecoration))?;
Ok(Self::new(translation_key, parameters, style))
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ChatType {
pub chat: ChatDecoration,
pub narration: ChatDecoration,
}
impl ChatType {
#[must_use]
pub const fn new(chat: ChatDecoration, narration: ChatDecoration) -> Self {
Self { chat, narration }
}
}
impl TypeCodec for ChatType {
fn encode(&self, writer: &mut impl std::io::Write) -> Result<(), CodecError> {
self.chat
.encode(writer)
.map_err(|error| error.with_context(CodecKind::ChatType))?;
self.narration
.encode(writer)
.map_err(|error| error.with_context(CodecKind::ChatType))
}
fn decode(reader: &mut impl std::io::Read) -> Result<Self, CodecError> {
let chat = ChatDecoration::decode(reader)
.map_err(|error| error.with_context(CodecKind::ChatType))?;
let narration = ChatDecoration::decode(reader)
.map_err(|error| error.with_context(CodecKind::ChatType))?;
Ok(Self::new(chat, narration))
}
}