valence_nbt/
value.rs

1#![allow(clippy::cast_lossless)] // TODO: Remove me.
2
3use std::borrow::Cow;
4use std::hash::Hash;
5
6use crate::tag::Tag;
7use crate::{Compound, List};
8
9/// Represents an arbitrary NBT value.
10#[derive(Clone, Debug)]
11pub enum Value<S = String> {
12    Byte(i8),
13    Short(i16),
14    Int(i32),
15    Long(i64),
16    Float(f32),
17    Double(f64),
18    ByteArray(Vec<i8>),
19    String(S),
20    List(List<S>),
21    Compound(Compound<S>),
22    IntArray(Vec<i32>),
23    LongArray(Vec<i64>),
24}
25
26/// Represents a reference to an arbitrary NBT value, where the tag is not part
27/// of the reference.
28#[derive(Copy, Clone, Debug)]
29pub enum ValueRef<'a, S = String> {
30    Byte(&'a i8),
31    Short(&'a i16),
32    Int(&'a i32),
33    Long(&'a i64),
34    Float(&'a f32),
35    Double(&'a f64),
36    ByteArray(&'a [i8]),
37    String(&'a S),
38    List(&'a List<S>),
39    Compound(&'a Compound<S>),
40    IntArray(&'a [i32]),
41    LongArray(&'a [i64]),
42}
43
44/// Represents a mutable reference to an arbitrary NBT value, where the tag is
45/// not part of the reference.
46#[derive(Debug)]
47pub enum ValueMut<'a, S = String> {
48    Byte(&'a mut i8),
49    Short(&'a mut i16),
50    Int(&'a mut i32),
51    Long(&'a mut i64),
52    Float(&'a mut f32),
53    Double(&'a mut f64),
54    ByteArray(&'a mut Vec<i8>),
55    String(&'a mut S),
56    List(&'a mut List<S>),
57    Compound(&'a mut Compound<S>),
58    IntArray(&'a mut Vec<i32>),
59    LongArray(&'a mut Vec<i64>),
60}
61
62macro_rules! impl_value {
63    ($name:ident, $($lifetime:lifetime)?, ($($deref:tt)*), $($reference:tt)*) => {
64        macro_rules! as_number {
65            ($method_name:ident, $ty:ty, $($deref)*) => {
66                #[doc = concat!("If this value is a number, returns the `", stringify!($ty), "` representation of this value.")]
67                pub fn $method_name(&self) -> Option<$ty> {
68                    #[allow(trivial_numeric_casts)]
69                    match self {
70                        Self::Byte(v) => Some($($deref)* v as $ty),
71                        Self::Short(v) => Some($($deref)* v as $ty),
72                        Self::Int(v) => Some($($deref)* v as $ty),
73                        Self::Long(v) => Some($($deref)* v as $ty),
74                        Self::Float(v) => Some(v.floor() as $ty),
75                        Self::Double(v) => Some(v.floor() as $ty),
76                        _ => None,
77                    }
78                }
79            }
80        }
81
82        macro_rules! as_number_float {
83            ($method_name:ident, $ty:ty, $($deref)*) => {
84                #[doc = concat!("If this value is a number, returns the `", stringify!($ty), "` representation of this value.")]
85                pub fn $method_name(&self) -> Option<$ty> {
86                    #[allow(trivial_numeric_casts)]
87                    match self {
88                        Self::Byte(v) => Some($($deref)* v as $ty),
89                        Self::Short(v) => Some($($deref)* v as $ty),
90                        Self::Int(v) => Some($($deref)* v as $ty),
91                        Self::Long(v) => Some($($deref)* v as $ty),
92                        Self::Float(v) => Some($($deref)* v as $ty),
93                        Self::Double(v) => Some($($deref)* v as $ty),
94                        _ => None,
95                    }
96                }
97            }
98        }
99
100        impl <$($lifetime,)? S> $name<$($lifetime,)? S> {
101            /// Returns the type of this value.
102            pub fn tag(&self) -> Tag {
103                match self {
104                    Self::Byte(_) => Tag::Byte,
105                    Self::Short(_) => Tag::Short,
106                    Self::Int(_) => Tag::Int,
107                    Self::Long(_) => Tag::Long,
108                    Self::Float(_) => Tag::Float,
109                    Self::Double(_) => Tag::Double,
110                    Self::ByteArray(_) => Tag::ByteArray,
111                    Self::String(_) => Tag::String,
112                    Self::List(_) => Tag::List,
113                    Self::Compound(_) => Tag::Compound,
114                    Self::IntArray(_) => Tag::IntArray,
115                    Self::LongArray(_) => Tag::LongArray,
116                }
117            }
118
119            /// Returns whether this value is a number, i.e. a byte, short, int, long, float or double.
120            pub fn is_number(&self) -> bool {
121                match self {
122                    Self::Byte(_) | Self::Short(_) | Self::Int(_) | Self::Long(_) | Self::Float(_) | Self::Double(_) => true,
123                    _ => false,
124                }
125            }
126
127            as_number!(as_i8, i8, $($deref)*);
128            as_number!(as_i16, i16, $($deref)*);
129            as_number!(as_i32, i32, $($deref)*);
130            as_number!(as_i64, i64, $($deref)*);
131            as_number_float!(as_f32, f32, $($deref)*);
132            as_number_float!(as_f64, f64, $($deref)*);
133
134            /// If this value is a number, returns the `bool` representation of this value.
135            pub fn as_bool(&self) -> Option<bool> {
136                self.as_i8().map(|v| v != 0)
137            }
138        }
139
140        impl <$($lifetime,)? S> From<$($reference)* i8> for $name<$($lifetime,)? S> {
141            fn from(v: $($reference)* i8) -> Self {
142                Self::Byte(v)
143            }
144        }
145
146        impl <$($lifetime,)? S> From<$($reference)* i16> for $name<$($lifetime,)? S> {
147            fn from(v: $($reference)* i16) -> Self {
148                Self::Short(v)
149            }
150        }
151
152        impl <$($lifetime,)? S> From<$($reference)* i32> for $name<$($lifetime,)? S> {
153            fn from(v: $($reference)* i32) -> Self {
154                Self::Int(v)
155            }
156        }
157
158        impl <$($lifetime,)? S> From<$($reference)* i64> for $name<$($lifetime,)? S> {
159            fn from(v: $($reference)* i64) -> Self {
160                Self::Long(v)
161            }
162        }
163
164        impl <$($lifetime,)? S> From<$($reference)* f32> for $name<$($lifetime,)? S> {
165            fn from(v: $($reference)* f32) -> Self {
166                Self::Float(v)
167            }
168        }
169
170        impl <$($lifetime,)? S> From<$($reference)* f64> for $name<$($lifetime,)? S> {
171            fn from(v: $($reference)* f64) -> Self {
172                Self::Double(v)
173            }
174        }
175
176        impl <$($lifetime,)? S> From<$($reference)* List<S>> for $name<$($lifetime,)? S> {
177            fn from(v: $($reference)* List<S>) -> Self {
178                Self::List(v)
179            }
180        }
181
182        impl <$($lifetime,)? S> From<$($reference)* Compound<S>> for $name<$($lifetime,)? S> {
183            fn from(v: $($reference)* Compound<S>) -> Self {
184                Self::Compound(v)
185            }
186        }
187
188        impl <$($lifetime,)? S> PartialEq<Self> for $name<$($lifetime,)? S> where S: Ord + Hash {
189            fn eq(&self, other: &Self) -> bool {
190                match self {
191                    Self::Byte(v) => matches!(other, Self::Byte(other_v) if v == other_v),
192                    Self::Short(v) => matches!(other, Self::Short(other_v) if v == other_v),
193                    Self::Int(v) => matches!(other, Self::Int(other_v) if v == other_v),
194                    Self::Long(v) => matches!(other, Self::Long(other_v) if v == other_v),
195                    Self::Float(v) => matches!(other, Self::Float(other_v) if v == other_v),
196                    Self::Double(v) => matches!(other, Self::Double(other_v) if v == other_v),
197                    Self::ByteArray(v) => matches!(other, Self::ByteArray(other_v) if v == other_v),
198                    Self::String(v) => matches!(other, Self::String(other_v) if v == other_v),
199                    Self::List(v) => matches!(other, Self::List(other_v) if v == other_v),
200                    Self::Compound(v) => matches!(other, Self::Compound(other_v) if v == other_v),
201                    Self::IntArray(v) => matches!(other, Self::IntArray(other_v) if v == other_v),
202                    Self::LongArray(v) => matches!(other, Self::LongArray(other_v) if v == other_v),
203                }
204            }
205        }
206    }
207}
208
209impl_value!(Value,,(*),);
210impl_value!(ValueRef, 'a, (**), &'a);
211impl_value!(ValueMut, 'a, (**), &'a mut);
212
213impl<S> Value<S> {
214    /// Converts a reference to a value to a [`ValueRef`].
215    pub fn as_value_ref(&self) -> ValueRef<S> {
216        match self {
217            Value::Byte(v) => ValueRef::Byte(v),
218            Value::Short(v) => ValueRef::Short(v),
219            Value::Int(v) => ValueRef::Int(v),
220            Value::Long(v) => ValueRef::Long(v),
221            Value::Float(v) => ValueRef::Float(v),
222            Value::Double(v) => ValueRef::Double(v),
223            Value::ByteArray(v) => ValueRef::ByteArray(&v[..]),
224            Value::String(v) => ValueRef::String(v),
225            Value::List(v) => ValueRef::List(v),
226            Value::Compound(v) => ValueRef::Compound(v),
227            Value::IntArray(v) => ValueRef::IntArray(&v[..]),
228            Value::LongArray(v) => ValueRef::LongArray(&v[..]),
229        }
230    }
231
232    /// Converts a mutable reference to a value to a [`ValueMut`].
233    pub fn as_value_mut(&mut self) -> ValueMut<S> {
234        match self {
235            Value::Byte(v) => ValueMut::Byte(v),
236            Value::Short(v) => ValueMut::Short(v),
237            Value::Int(v) => ValueMut::Int(v),
238            Value::Long(v) => ValueMut::Long(v),
239            Value::Float(v) => ValueMut::Float(v),
240            Value::Double(v) => ValueMut::Double(v),
241            Value::ByteArray(v) => ValueMut::ByteArray(v),
242            Value::String(v) => ValueMut::String(v),
243            Value::List(v) => ValueMut::List(v),
244            Value::Compound(v) => ValueMut::Compound(v),
245            Value::IntArray(v) => ValueMut::IntArray(v),
246            Value::LongArray(v) => ValueMut::LongArray(v),
247        }
248    }
249}
250
251impl<S> ValueRef<'_, S>
252where
253    S: Clone,
254{
255    /// Clones this value reference to a new owned [`Value`].
256    pub fn to_value(&self) -> Value<S> {
257        match *self {
258            ValueRef::Byte(v) => Value::Byte(*v),
259            ValueRef::Short(v) => Value::Short(*v),
260            ValueRef::Int(v) => Value::Int(*v),
261            ValueRef::Long(v) => Value::Long(*v),
262            ValueRef::Float(v) => Value::Float(*v),
263            ValueRef::Double(v) => Value::Double(*v),
264            ValueRef::ByteArray(v) => Value::ByteArray(v.to_vec()),
265            ValueRef::String(v) => Value::String(v.to_owned()),
266            ValueRef::List(v) => Value::List(v.clone()),
267            ValueRef::Compound(v) => Value::Compound(v.clone()),
268            ValueRef::IntArray(v) => Value::IntArray(v.to_vec()),
269            ValueRef::LongArray(v) => Value::LongArray(v.to_vec()),
270        }
271    }
272}
273
274impl<S> ValueMut<'_, S>
275where
276    S: Clone,
277{
278    /// Clones this mutable value reference to a new owned [`Value`].
279    pub fn to_value(&self) -> Value<S> {
280        match self {
281            ValueMut::Byte(v) => Value::Byte(**v),
282            ValueMut::Short(v) => Value::Short(**v),
283            ValueMut::Int(v) => Value::Int(**v),
284            ValueMut::Long(v) => Value::Long(**v),
285            ValueMut::Float(v) => Value::Float(**v),
286            ValueMut::Double(v) => Value::Double(**v),
287            ValueMut::ByteArray(v) => Value::ByteArray((*v).clone()),
288            ValueMut::String(v) => Value::String((*v).clone()),
289            ValueMut::List(v) => Value::List((*v).clone()),
290            ValueMut::Compound(v) => Value::Compound((*v).clone()),
291            ValueMut::IntArray(v) => Value::IntArray((*v).clone()),
292            ValueMut::LongArray(v) => Value::LongArray((*v).clone()),
293        }
294    }
295}
296
297impl<'a, S> ValueMut<'a, S> {
298    /// Downgrades this mutable value reference into an immutable [`ValueRef`].
299    pub fn into_value_ref(self) -> ValueRef<'a, S> {
300        match self {
301            ValueMut::Byte(v) => ValueRef::Byte(v),
302            ValueMut::Short(v) => ValueRef::Short(v),
303            ValueMut::Int(v) => ValueRef::Int(v),
304            ValueMut::Long(v) => ValueRef::Long(v),
305            ValueMut::Float(v) => ValueRef::Float(v),
306            ValueMut::Double(v) => ValueRef::Double(v),
307            ValueMut::ByteArray(v) => ValueRef::ByteArray(&v[..]),
308            ValueMut::String(v) => ValueRef::String(v),
309            ValueMut::List(v) => ValueRef::List(v),
310            ValueMut::Compound(v) => ValueRef::Compound(v),
311            ValueMut::IntArray(v) => ValueRef::IntArray(&v[..]),
312            ValueMut::LongArray(v) => ValueRef::LongArray(&v[..]),
313        }
314    }
315}
316
317/// Bools are usually represented as `0` or `1` bytes in NBT.
318impl<S> From<bool> for Value<S> {
319    fn from(b: bool) -> Self {
320        Value::Byte(b.into())
321    }
322}
323
324impl<S> From<Vec<i8>> for Value<S> {
325    fn from(v: Vec<i8>) -> Self {
326        Self::ByteArray(v)
327    }
328}
329
330impl From<String> for Value<String> {
331    fn from(v: String) -> Self {
332        Self::String(v)
333    }
334}
335
336impl From<&String> for Value<String> {
337    fn from(value: &String) -> Self {
338        Self::String(value.clone())
339    }
340}
341
342impl<'a> From<&'a str> for Value<String> {
343    fn from(v: &'a str) -> Self {
344        Self::String(v.to_owned())
345    }
346}
347
348impl<'a> From<Cow<'a, str>> for Value<String> {
349    fn from(v: Cow<'a, str>) -> Self {
350        Self::String(v.into_owned())
351    }
352}
353
354impl From<String> for Value<Cow<'_, str>> {
355    fn from(v: String) -> Self {
356        Self::String(Cow::Owned(v))
357    }
358}
359
360impl<'a> From<&'a String> for Value<Cow<'a, str>> {
361    fn from(v: &'a String) -> Self {
362        Self::String(Cow::Borrowed(v))
363    }
364}
365
366impl<'a> From<&'a str> for Value<Cow<'a, str>> {
367    fn from(v: &'a str) -> Self {
368        Self::String(Cow::Borrowed(v))
369    }
370}
371
372impl<'a> From<Cow<'a, str>> for Value<Cow<'a, str>> {
373    fn from(v: Cow<'a, str>) -> Self {
374        Self::String(v)
375    }
376}
377
378#[cfg(feature = "java_string")]
379impl From<java_string::JavaString> for Value<java_string::JavaString> {
380    fn from(v: java_string::JavaString) -> Self {
381        Self::String(v)
382    }
383}
384
385#[cfg(feature = "java_string")]
386impl From<&java_string::JavaString> for Value<java_string::JavaString> {
387    fn from(v: &java_string::JavaString) -> Self {
388        Self::String(v.clone())
389    }
390}
391
392#[cfg(feature = "java_string")]
393impl<'a> From<&'a java_string::JavaStr> for Value<java_string::JavaString> {
394    fn from(v: &'a java_string::JavaStr) -> Self {
395        Self::String(v.to_owned())
396    }
397}
398
399#[cfg(feature = "java_string")]
400impl<'a> From<Cow<'a, java_string::JavaStr>> for Value<java_string::JavaString> {
401    fn from(v: Cow<'a, java_string::JavaStr>) -> Self {
402        Self::String(v.into_owned())
403    }
404}
405
406#[cfg(feature = "java_string")]
407impl From<String> for Value<java_string::JavaString> {
408    fn from(v: String) -> Self {
409        Self::String(java_string::JavaString::from(v))
410    }
411}
412
413#[cfg(feature = "java_string")]
414impl From<&String> for Value<java_string::JavaString> {
415    fn from(v: &String) -> Self {
416        Self::String(java_string::JavaString::from(v))
417    }
418}
419
420#[cfg(feature = "java_string")]
421impl<'a> From<&'a str> for Value<java_string::JavaString> {
422    fn from(v: &'a str) -> Self {
423        Self::String(java_string::JavaString::from(v))
424    }
425}
426
427#[cfg(feature = "java_string")]
428impl<'a> From<Cow<'a, str>> for Value<java_string::JavaString> {
429    fn from(v: Cow<'a, str>) -> Self {
430        Self::String(java_string::JavaString::from(v))
431    }
432}
433
434#[cfg(feature = "java_string")]
435impl From<java_string::JavaString> for Value<Cow<'_, java_string::JavaStr>> {
436    fn from(v: java_string::JavaString) -> Self {
437        Self::String(Cow::Owned(v))
438    }
439}
440
441#[cfg(feature = "java_string")]
442impl<'a> From<&'a java_string::JavaString> for Value<Cow<'a, java_string::JavaStr>> {
443    fn from(v: &'a java_string::JavaString) -> Self {
444        Self::String(Cow::Borrowed(v))
445    }
446}
447
448#[cfg(feature = "java_string")]
449impl<'a> From<&'a java_string::JavaStr> for Value<Cow<'a, java_string::JavaStr>> {
450    fn from(v: &'a java_string::JavaStr) -> Self {
451        Self::String(Cow::Borrowed(v))
452    }
453}
454
455#[cfg(feature = "java_string")]
456impl<'a> From<Cow<'a, java_string::JavaStr>> for Value<Cow<'a, java_string::JavaStr>> {
457    fn from(v: Cow<'a, java_string::JavaStr>) -> Self {
458        Self::String(v)
459    }
460}
461
462#[cfg(feature = "java_string")]
463impl From<String> for Value<Cow<'_, java_string::JavaStr>> {
464    fn from(v: String) -> Self {
465        Self::String(Cow::Owned(java_string::JavaString::from(v)))
466    }
467}
468
469#[cfg(feature = "java_string")]
470impl<'a> From<&'a String> for Value<Cow<'a, java_string::JavaStr>> {
471    fn from(v: &'a String) -> Self {
472        Self::String(Cow::Borrowed(java_string::JavaStr::from_str(v)))
473    }
474}
475
476#[cfg(feature = "java_string")]
477impl<'a> From<&'a str> for Value<Cow<'a, java_string::JavaStr>> {
478    fn from(v: &'a str) -> Self {
479        Self::String(Cow::Borrowed(java_string::JavaStr::from_str(v)))
480    }
481}
482
483#[cfg(feature = "java_string")]
484impl<'a> From<Cow<'a, str>> for Value<Cow<'a, java_string::JavaStr>> {
485    fn from(v: Cow<'a, str>) -> Self {
486        Self::String(match v {
487            Cow::Borrowed(str) => Cow::Borrowed(java_string::JavaStr::from_str(str)),
488            Cow::Owned(str) => Cow::Owned(java_string::JavaString::from(str)),
489        })
490    }
491}
492
493impl<S> From<Vec<i32>> for Value<S> {
494    fn from(v: Vec<i32>) -> Self {
495        Self::IntArray(v)
496    }
497}
498
499impl<S> From<Vec<i64>> for Value<S> {
500    fn from(v: Vec<i64>) -> Self {
501        Self::LongArray(v)
502    }
503}
504
505impl<S> From<ValueRef<'_, S>> for Value<S>
506where
507    S: Clone,
508{
509    fn from(v: ValueRef<S>) -> Self {
510        v.to_value()
511    }
512}
513
514impl<S> From<&ValueRef<'_, S>> for Value<S>
515where
516    S: Clone,
517{
518    fn from(v: &ValueRef<S>) -> Self {
519        v.to_value()
520    }
521}
522
523impl<S> From<ValueMut<'_, S>> for Value<S>
524where
525    S: Clone,
526{
527    fn from(v: ValueMut<S>) -> Self {
528        v.to_value()
529    }
530}
531
532impl<S> From<&ValueMut<'_, S>> for Value<S>
533where
534    S: Clone,
535{
536    fn from(v: &ValueMut<S>) -> Self {
537        v.to_value()
538    }
539}
540
541#[cfg(feature = "uuid")]
542impl<S> From<uuid::Uuid> for Value<S> {
543    fn from(value: uuid::Uuid) -> Self {
544        let (most, least) = value.as_u64_pair();
545
546        let first = (most >> 32) as i32;
547        let second = most as i32;
548        let third = (least >> 32) as i32;
549        let fourth = least as i32;
550
551        Value::IntArray(vec![first, second, third, fourth])
552    }
553}
554
555#[cfg(feature = "valence_ident")]
556impl<I, S> From<valence_ident::Ident<I>> for Value<S>
557where
558    I: Into<Value<S>>,
559{
560    fn from(value: valence_ident::Ident<I>) -> Self {
561        value.into_inner().into()
562    }
563}
564
565impl<'a> From<&'a [i8]> for ValueRef<'a> {
566    fn from(v: &'a [i8]) -> Self {
567        Self::ByteArray(v)
568    }
569}
570
571impl<'a> From<&'a String> for ValueRef<'a, String> {
572    fn from(v: &'a String) -> ValueRef<'a> {
573        Self::String(v)
574    }
575}
576
577impl<'a, S> From<&'a [i32]> for ValueRef<'a, S> {
578    fn from(v: &'a [i32]) -> Self {
579        Self::IntArray(v)
580    }
581}
582
583impl<'a, S> From<&'a [i64]> for ValueRef<'a, S> {
584    fn from(v: &'a [i64]) -> Self {
585        Self::LongArray(v)
586    }
587}
588
589impl<'a, S> From<&'a Value<S>> for ValueRef<'a, S> {
590    fn from(v: &'a Value<S>) -> Self {
591        v.as_value_ref()
592    }
593}
594
595impl<'a, S> From<ValueMut<'a, S>> for ValueRef<'a, S> {
596    fn from(v: ValueMut<'a, S>) -> Self {
597        v.into_value_ref()
598    }
599}
600
601#[cfg(feature = "valence_ident")]
602impl<'a> From<&'a valence_ident::Ident<String>> for ValueRef<'a, String> {
603    fn from(v: &'a valence_ident::Ident<String>) -> Self {
604        Self::String(v.as_ref())
605    }
606}
607
608impl<'a, S> From<&'a mut Vec<i8>> for ValueMut<'a, S> {
609    fn from(v: &'a mut Vec<i8>) -> Self {
610        Self::ByteArray(v)
611    }
612}
613
614impl<'a> From<&'a mut String> for ValueMut<'a, String> {
615    fn from(v: &'a mut String) -> Self {
616        Self::String(v)
617    }
618}
619
620impl<'a, S> From<&'a mut Vec<i32>> for ValueMut<'a, S> {
621    fn from(v: &'a mut Vec<i32>) -> Self {
622        Self::IntArray(v)
623    }
624}
625
626impl<'a, S> From<&'a mut Vec<i64>> for ValueMut<'a, S> {
627    fn from(v: &'a mut Vec<i64>) -> Self {
628        Self::LongArray(v)
629    }
630}
631
632impl<'a, S> From<&'a mut Value<S>> for ValueMut<'a, S> {
633    fn from(v: &'a mut Value<S>) -> Self {
634        v.as_value_mut()
635    }
636}