aoe2_probe/utils/
string.rs1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 io::Source,
7 parse::{Decode, Encode},
8};
9
10#[derive(Clone, Debug, Serialize, Deserialize)]
11pub struct DynString<T: Numeric> {
12 capacity: T,
13 raw: String,
14}
15
16impl<T> DynString<T>
17where
18 T: Numeric,
19{
20 pub fn new(raw: &str) -> Self {
21 DynString {
22 capacity: T::from_usize(raw.len()),
23 raw: raw.to_string(),
24 }
25 }
26
27 pub fn with_capacity(capacity: T, raw: &str) -> Self {
28 if capacity.to_usize() < raw.len() {
29 panic!("Content is over capacity!")
30 }
31 DynString {
32 capacity,
33 raw: raw.to_string(),
34 }
35 }
36
37 pub fn capacity(&self) -> T {
38 self.capacity
39 }
40
41 pub fn content(&self) -> &String {
42 &self.raw
43 }
44
45 pub fn content_mut(&mut self) -> &mut String {
46 &mut self.raw
47 }
48
49 pub fn set_content(&mut self, content: &str) {
50 if self.capacity.to_usize() < content.len() {
51 self.capacity = T::from_usize(content.len());
52 }
53
54 self.raw = content.to_string();
55 }
56}
57
58impl<T> Encode for DynString<T>
59where
60 T: Numeric,
61{
62 fn to_le_vec(&self) -> Vec<u8> {
63 let container_len: usize = if self.capacity.to_usize() < self.raw.len() {
64 self.capacity.to_usize()
65 } else {
66 self.raw.len()
67 };
68
69 let mut vec = Vec::<u8>::new();
70 let mut prefix = self.capacity.to_le_vec();
71 let content = self.raw.clone().into_bytes();
72 let mut container = vec![0; container_len];
73 for (index, _) in content.iter().enumerate() {
74 container[index] = content[index];
75 }
76 vec.append(&mut prefix);
77 vec.append(&mut container);
78 vec
79 }
80}
81
82impl Decode for DynString<u16> {
83 fn from_le_vec(source: &mut Source) -> Result<Self, String> {
84 let capacity = u16::from_le_vec(source)?;
85 let raw = String::from_utf8_lossy(&source.get_vec(capacity as usize)?[..]).to_string();
86
87 Ok(DynString::with_capacity(capacity, &raw))
88 }
89}
90
91impl Decode for DynString<u32> {
92 fn from_le_vec(source: &mut Source) -> Result<Self, String> {
93 let capacity = u32::from_le_vec(source)?;
94 let raw = String::from_utf8_lossy(&source.get_vec(capacity as usize)?[..]).to_string();
95
96 Ok(DynString::with_capacity(capacity, &raw))
97 }
98}
99
100pub trait Numeric: Copy + Encode {
101 fn to_usize(&self) -> usize;
102 fn from_usize(num: usize) -> Self;
103}
104
105impl Numeric for u16 {
106 fn to_usize(&self) -> usize {
107 *self as usize
108 }
109
110 fn from_usize(num: usize) -> Self {
111 num as u16
112 }
113}
114impl Numeric for u32 {
115 fn to_usize(&self) -> usize {
116 *self as usize
117 }
118
119 fn from_usize(num: usize) -> Self {
120 num as u32
121 }
122}
123
124#[derive(Clone, Debug, Serialize, Deserialize)]
125pub struct C4 {
126 raw: String,
127}
128
129impl C4 {
130 pub fn new(content: &str) -> Self {
131 if content.len() > 4 {
132 panic!("Out of the fixed capacity!")
133 }
134
135 C4 {
136 raw: content.to_string(),
137 }
138 }
139
140 pub fn content(&self) -> &String {
141 &self.raw
142 }
143
144 pub fn set_content(&mut self, content: &str) {
145 if content.len() > 4 {
146 panic!("Out of the fixed capacity!")
147 }
148 self.raw = content.to_string();
149 }
150}
151
152impl Decode for C4 {
153 fn from_le_vec(source: &mut Source) -> Result<Self, String> {
154 let raw = String::from_utf8_lossy(&source.get_vec(4_usize)?[..]).to_string();
155
156 Ok(C4::new(&raw))
157 }
158}
159
160impl Encode for C4 {
161 fn to_le_vec(&self) -> Vec<u8> {
162 let content = self.raw.clone().into_bytes();
163 let mut container = vec![0; 4];
164 for (index, _) in content.iter().enumerate() {
165 container[index] = content[index];
166 }
167 container
168 }
169}
170
171#[derive(Clone, Serialize, Deserialize)]
172pub struct C256 {
173 raw: String,
174}
175
176impl C256 {
177 pub fn new(content: &str) -> Self {
178 if content.len() > 256 {
179 panic!("Out of the fixed capacity!")
180 }
181
182 C256 {
183 raw: content.to_string(),
184 }
185 }
186
187 pub fn content(&self) -> &String {
188 &self.raw
189 }
190
191 pub fn set_content(&mut self, content: &str) {
192 if content.len() > 256 {
193 panic!("Out of the fixed capacity!")
194 }
195 self.raw = content.to_string();
196 }
197}
198
199impl Decode for C256 {
200 fn from_le_vec(source: &mut Source) -> Result<Self, String> {
201 let raw = String::from_utf8_lossy(&source.get_vec(256_usize)?[..]).to_string();
202 Ok(C256::new(&raw))
203 }
204}
205
206impl Encode for C256 {
207 fn to_le_vec(&self) -> Vec<u8> {
208 let content = self.raw.clone().into_bytes();
209 let mut container = vec![0; 256];
210 for (index, _) in content.iter().enumerate() {
211 container[index] = content[index];
212 }
213 container
214 }
215}
216
217impl fmt::Debug for C256 {
218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219 write!(f, "{}", self.raw.trim_matches(char::from(0)))
220 }
221}