1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use crate::bin_decode::{NbtParse, ParseError, Reader};
use byteorder::{BigEndian, ByteOrder};
use cesu8::{from_java_cesu8, Cesu8DecodingError};
use core::ops::Deref;
use std::borrow::Cow;
use std::fmt;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct NbtString<'a> {
data: &'a [u8],
}
impl<'a> NbtParse<'a> for NbtString<'a> {
fn read(reader: &mut Reader<'a>) -> Result<Self, ParseError> {
let length = BigEndian::read_u16(reader.advance(2)?);
let data = reader.advance(length as usize)?;
Ok(NbtString { data })
}
}
impl<'a> NbtString<'a> {
#[doc(hidden)]
pub fn new(data: &'a [u8]) -> NbtString<'a> {
NbtString { data }
}
pub fn decode(&self) -> Result<Cow<str>, Cesu8DecodingError> {
from_java_cesu8(self.data)
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
}
impl<'a, T> PartialEq<T> for NbtString<'a>
where
T: AsRef<str>,
{
fn eq(&self, other: &T) -> bool {
if let Ok(result) = self.decode() {
result == other.as_ref()
} else {
false
}
}
}
impl<'a> Deref for NbtString<'a> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<'a> fmt::Debug for NbtString<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
if let Ok(result) = self.decode() {
fmt::Debug::fmt(&result, fmt)
} else {
write!(fmt, "\"")?;
for ch in self.data {
match ch {
0 => write!(fmt, r"\0")?,
1..=0x7F => write!(fmt, "{}", (*ch as char).escape_default())?,
0x80..=0xFF => write!(fmt, r"\x{:02X}", ch)?,
}
}
write!(fmt, "\"")
}
}
}