steel_registry/data_components/components/
ominous_bottle_amplifier.rs1use std::io::{Cursor, Result, Write};
4
5use simdnbt::owned::NbtTag;
6use simdnbt::{FromNbtTag, ToNbtTag};
7use steel_utils::codec::VarInt;
8use steel_utils::hash::{ComponentHasher, HashComponent};
9use steel_utils::nbt::NbtNumeric as _;
10use steel_utils::serial::{ReadFrom, WriteTo};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct OminousBottleAmplifier {
14 value: i32,
15}
16
17impl OminousBottleAmplifier {
18 pub const EFFECT_DURATION: i32 = 120_000;
19 pub const MIN_AMPLIFIER: i32 = 0;
20 pub const MAX_AMPLIFIER: i32 = 4;
21
22 #[must_use]
23 pub const fn new(value: i32) -> Self {
24 Self { value }
25 }
26
27 #[must_use]
28 pub const fn value(self) -> i32 {
29 self.value
30 }
31}
32
33impl WriteTo for OminousBottleAmplifier {
34 fn write(&self, writer: &mut impl Write) -> Result<()> {
35 VarInt(self.value).write(writer)
36 }
37}
38
39impl ReadFrom for OminousBottleAmplifier {
40 fn read(data: &mut Cursor<&[u8]>) -> Result<Self> {
41 Ok(Self::new(VarInt::read(data)?.0))
42 }
43}
44
45impl ToNbtTag for OminousBottleAmplifier {
46 fn to_nbt_tag(self) -> NbtTag {
47 NbtTag::Int(self.value)
48 }
49}
50
51impl FromNbtTag for OminousBottleAmplifier {
52 fn from_nbt_tag(tag: simdnbt::borrow::NbtTag<'_, '_>) -> Option<Self> {
53 let value = tag.codec_i32()?;
54 (Self::MIN_AMPLIFIER..=Self::MAX_AMPLIFIER)
55 .contains(&value)
56 .then(|| Self::new(value))
57 }
58}
59
60impl HashComponent for OminousBottleAmplifier {
61 fn hash_component(&self, hasher: &mut ComponentHasher) {
62 hasher.put_int(self.value);
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use std::io::Cursor;
69
70 use simdnbt::FromNbtTag as _;
71 use simdnbt::borrow::read_tag;
72 use simdnbt::owned::NbtTag;
73 use steel_utils::codec::VarInt;
74 use steel_utils::serial::{ReadFrom as _, WriteTo as _};
75
76 use super::OminousBottleAmplifier;
77
78 fn parse(tag: NbtTag) -> Option<OminousBottleAmplifier> {
79 let mut bytes = Vec::new();
80 tag.write(&mut bytes);
81 let borrowed = read_tag(&mut Cursor::new(bytes.as_slice())).ok()?;
82 OminousBottleAmplifier::from_nbt_tag(borrowed.as_tag())
83 }
84
85 #[test]
86 fn persistent_codec_enforces_vanilla_range() {
87 assert_eq!(parse(NbtTag::Byte(0)), Some(OminousBottleAmplifier::new(0)));
88 assert_eq!(parse(NbtTag::Long(4)), Some(OminousBottleAmplifier::new(4)));
89 assert_eq!(parse(NbtTag::Int(-1)), None);
90 assert_eq!(parse(NbtTag::Int(5)), None);
91 }
92
93 #[test]
94 fn network_codec_accepts_any_varint_like_vanilla_constructor() {
95 for value in [-1, 0, 4, 5, i32::MAX] {
96 let mut encoded = Vec::new();
97 VarInt(value)
98 .write(&mut encoded)
99 .expect("amplifier should encode");
100 assert_eq!(
101 OminousBottleAmplifier::read(&mut Cursor::new(encoded.as_slice()))
102 .expect("amplifier should decode"),
103 OminousBottleAmplifier::new(value)
104 );
105 }
106 }
107}