luanti_protocol/types/
strings.rs1use crate::wire::{
2 deser::{Deserialize, DeserializeError, DeserializeResult, Deserializer},
3 ser::{Serialize, SerializeResult, Serializer},
4};
5use anyhow::bail;
6use log::trace;
7use std::ops::DerefMut;
8use std::{marker::PhantomData, ops::Deref};
9
10#[derive(Clone, PartialEq)]
15pub struct ByteString(pub Vec<u8>);
16
17impl std::fmt::Debug for ByteString {
18 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 std::fmt::Debug::fmt(&self.escape_ascii(), formatter)
21 }
22}
23
24impl ByteString {
25 #[must_use]
26 pub fn as_bytes(&self) -> &[u8] {
27 &self.0
28 }
29
30 #[must_use]
31 pub fn len(&self) -> usize {
32 self.0.len()
33 }
34
35 #[must_use]
36 pub fn is_empty(&self) -> bool {
37 self.0.is_empty()
38 }
39
40 #[must_use]
41 pub fn escape_ascii(&self) -> String {
42 self.0.escape_ascii().to_string()
43 }
44}
45
46impl Deref for ByteString {
47 type Target = [u8];
48
49 fn deref(&self) -> &Self::Target {
50 self.as_bytes()
51 }
52}
53
54impl DerefMut for ByteString {
55 fn deref_mut(&mut self) -> &mut Self::Target {
56 self.0.as_mut_slice()
57 }
58}
59
60impl From<Vec<u8>> for ByteString {
61 fn from(value: Vec<u8>) -> Self {
62 Self(value)
63 }
64}
65
66impl From<&[u8]> for ByteString {
67 fn from(value: &[u8]) -> Self {
68 Self(value.to_vec())
69 }
70}
71
72impl Serialize for str {
74 type Input = Self;
75
76 fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
77 u16::serialize(&u16::try_from(value.len())?, ser)?;
78 ser.write_bytes(value.as_bytes())
79 }
80}
81
82impl Serialize for String {
83 type Input = Self;
84 fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
85 <str as Serialize>::serialize(value, ser)
86 }
87}
88
89impl Deserialize for String {
90 type Output = Self;
91 fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self> {
92 let num_bytes = u16::deserialize(deser)? as usize;
93 trace!(
94 "String with {} bytes - {} bytes remaining",
95 num_bytes,
96 deser.remaining()
97 );
98 match std::str::from_utf8(deser.take(num_bytes)?) {
99 Ok(str) => Ok(str.into()),
100 Err(error) => bail!(DeserializeError::InvalidValue(error.to_string())),
101 }
102 }
103}
104
105#[derive(Debug, Clone, PartialEq)]
106pub struct LongString(PhantomData<String>);
107
108impl Serialize for LongString {
109 type Input = String;
110 fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
111 u32::serialize(&u32::try_from(value.len())?, ser)?;
112 ser.write_bytes(value.as_bytes())
113 }
114}
115
116impl Deserialize for LongString {
117 type Output = String;
118 fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self::Output> {
119 let num_bytes = u32::deserialize(deser)? as usize;
120 match std::str::from_utf8(deser.take(num_bytes)?) {
121 Ok(str) => Ok(str.into()),
122 Err(error) => bail!(DeserializeError::InvalidValue(error.to_string())),
123 }
124 }
125}
126
127#[derive(Debug, Clone, PartialEq)]
129pub struct WString(PhantomData<String>);
130
131impl Serialize for WString {
132 type Input = String;
133 fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
134 let enc: Vec<u16> = value.encode_utf16().collect();
135
136 u16::serialize(&u16::try_from(enc.len())?, ser)?;
137 let mut buf: Vec<u8> = vec![0; 2 * enc.len()];
139 let mut index: usize = 0;
140 for codepoint in enc {
141 buf[index] = (codepoint >> 8) as u8;
142 buf[index + 1] = codepoint as u8;
143 index += 2;
144 }
145 ser.write_bytes(&buf)
146 }
147}
148
149impl Deserialize for WString {
150 type Output = String;
151 fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self::Output> {
152 let length = u16::deserialize(deser)? as usize;
153 let raw = deser.take(2 * length)?;
154 let mut seq: Vec<u16> = vec![0; length];
155 for i in 0..length {
156 seq[i] = u16::from_be_bytes(raw[2 * i..2 * i + 2].try_into().unwrap());
157 }
158 match String::from_utf16(&seq) {
159 Ok(str) => Ok(str),
160 Err(err) => bail!(DeserializeError::InvalidValue(err.to_string())),
161 }
162 }
163}