use crate::{
TypeCodec,
basic::{Float, Identifier},
contextual::PrefixedOptional,
};
use mcproto_codec::error::{CodecError, CodecKind};
#[derive(Debug, Clone, PartialEq)]
pub struct SoundEvent {
pub sound_name: Identifier,
pub fixed_range: Option<Float>,
}
impl SoundEvent {
#[must_use]
pub const fn new(sound_name: Identifier, fixed_range: Option<Float>) -> Self {
Self {
sound_name,
fixed_range,
}
}
#[must_use]
pub const fn variable(sound_name: Identifier) -> Self {
Self::new(sound_name, None)
}
#[must_use]
pub const fn fixed(sound_name: Identifier, fixed_range: Float) -> Self {
Self::new(sound_name, Some(fixed_range))
}
#[must_use]
pub const fn has_fixed_range(&self) -> bool {
self.fixed_range.is_some()
}
}
impl TypeCodec for SoundEvent {
fn encode(&self, writer: &mut impl std::io::Write) -> Result<(), CodecError> {
self.sound_name
.encode(writer)
.map_err(|error| error.with_context(CodecKind::SoundEvent))?;
PrefixedOptional::from(self.fixed_range)
.encode(writer)
.map_err(|error| error.with_context(CodecKind::SoundEvent))
}
fn decode(reader: &mut impl std::io::Read) -> Result<Self, CodecError> {
let sound_name = Identifier::decode(reader)
.map_err(|error| error.with_context(CodecKind::SoundEvent))?;
let fixed_range = PrefixedOptional::<Float>::decode(reader)
.map_err(|error| error.with_context(CodecKind::SoundEvent))?
.into_option();
Ok(Self::new(sound_name, fixed_range))
}
}