1pub use crate::basic_types::{Compression, PasswordHashAlgo, Pointer};
2use std::collections::HashMap;
3
4#[derive(Debug, PartialEq, Eq)]
6pub struct Message {
7 pub id: Identifier,
8 pub objects: Vec<Object>,
9}
10
11impl Message {
12 pub fn new(id: Identifier, objects: Vec<Object>) -> Self {
15 Self { id, objects }
16 }
17}
18
19pub trait MessageType {
21 fn to_object(self) -> Object;
22 fn to_object_ref(&self) -> ObjectRef;
23 fn to_warray(vec: Vec<Self>) -> WArray
24 where
25 Self: Sized;
26}
27
28pub type WChar = i8;
32pub type WInteger = i32;
35pub type WLongInteger = i64;
38#[derive(Debug, PartialEq, Eq, Hash, Clone)]
46pub struct WString {
47 bytes: Option<Vec<u8>>,
48}
49
50impl WString {
51 pub fn new(bytes: Option<Vec<u8>>) -> Self {
52 Self { bytes }
53 }
54
55 pub fn from_ref(bytes: &[u8]) -> Self {
56 Self::new(Some(bytes.to_vec()))
57 }
58
59 pub fn bytes(&self) -> &Option<Vec<u8>> {
61 &self.bytes
62 }
63}
64
65pub type WBuffer = Option<Vec<u8>>;
69pub type WTime = u64;
72
73#[derive(Debug, PartialEq, Eq, Hash, Clone)]
88pub struct WHashtable {
89 pub keys: WArray,
90 pub vals: WArray,
91}
92
93#[derive(Debug, PartialEq, Eq, Hash, Clone)]
96pub struct GenericHdata {
97 pub hpath: WString, pub ppaths: Vec<Vec<Pointer>>,
99 pub set_values: Vec<HdataValues>,
103}
104
105impl GenericHdata {
106 pub fn sets(&self) -> Vec<HashMap<&Vec<u8>, ObjectRef>> {
111 let mut ret = vec![HashMap::new(); self.set_values[0].values.len()];
112 for hdata_values in self.set_values.iter() {
113 let values = hdata_values.values.to_ref_vec();
114 for (i, v) in values.into_iter().enumerate() {
115 ret[i].insert(&hdata_values.key, v);
116 }
117 }
118 ret
119 }
120}
121
122#[derive(Debug, PartialEq, Eq, Hash, Clone)]
123pub struct HdataValues {
124 pub key: Vec<u8>,
125 pub values: WArray,
126}
127
128#[derive(Debug, PartialEq, Eq, Hash, Clone)]
131pub struct WInfo {
132 pub name: WString,
133 pub value: WString,
134}
135
136#[derive(Debug, PartialEq, Eq, Hash, Clone)]
139pub struct WInfolist {
140 pub name: WString,
141 pub items: Vec<InfolistItem>,
142}
143
144#[derive(Debug, PartialEq, Eq, Hash, Clone)]
148pub struct InfolistItem {
149 pub variables: Vec<InfolistVariable>,
150}
151
152#[derive(Debug, PartialEq, Eq, Hash, Clone)]
156pub struct InfolistVariable {
157 pub name: WString,
158 pub value: Object,
159}
160
161impl MessageType for WChar {
162 fn to_object(self) -> Object {
163 Object::Chr(self)
164 }
165 fn to_object_ref(&self) -> ObjectRef {
166 ObjectRef::Chr(self)
167 }
168 fn to_warray(vec: Vec<Self>) -> WArray {
169 WArray::Chr(vec)
170 }
171}
172impl MessageType for WInteger {
173 fn to_object(self) -> Object {
174 Object::Int(self)
175 }
176 fn to_object_ref(&self) -> ObjectRef {
177 ObjectRef::Int(self)
178 }
179 fn to_warray(vec: Vec<Self>) -> WArray {
180 WArray::Int(vec)
181 }
182}
183impl MessageType for WLongInteger {
184 fn to_object(self) -> Object {
185 Object::Lon(self)
186 }
187 fn to_object_ref(&self) -> ObjectRef {
188 ObjectRef::Lon(self)
189 }
190 fn to_warray(vec: Vec<Self>) -> WArray {
191 WArray::Lon(vec)
192 }
193}
194impl MessageType for WString {
195 fn to_object(self) -> Object {
196 Object::Str(self)
197 }
198 fn to_object_ref(&self) -> ObjectRef {
199 ObjectRef::Str(self)
200 }
201 fn to_warray(vec: Vec<Self>) -> WArray {
202 WArray::Str(vec)
203 }
204}
205impl MessageType for WBuffer {
206 fn to_object(self) -> Object {
207 Object::Buf(self)
208 }
209 fn to_object_ref(&self) -> ObjectRef {
210 ObjectRef::Buf(self)
211 }
212 fn to_warray(vec: Vec<Self>) -> WArray {
213 WArray::Buf(vec)
214 }
215}
216impl MessageType for Pointer {
217 fn to_object(self) -> Object {
218 Object::Ptr(self)
219 }
220 fn to_object_ref(&self) -> ObjectRef {
221 ObjectRef::Ptr(self)
222 }
223 fn to_warray(vec: Vec<Self>) -> WArray {
224 WArray::Ptr(vec)
225 }
226}
227impl MessageType for WTime {
228 fn to_object(self) -> Object {
229 Object::Tim(self)
230 }
231 fn to_object_ref(&self) -> ObjectRef {
232 ObjectRef::Tim(self)
233 }
234 fn to_warray(vec: Vec<Self>) -> WArray {
235 WArray::Tim(vec)
236 }
237}
238impl MessageType for WHashtable {
239 fn to_object(self) -> Object {
240 Object::Htb(self)
241 }
242 fn to_object_ref(&self) -> ObjectRef {
243 ObjectRef::Htb(self)
244 }
245 fn to_warray(vec: Vec<Self>) -> WArray {
246 WArray::Htb(vec)
247 }
248}
249impl MessageType for GenericHdata {
250 fn to_object(self) -> Object {
251 Object::Hda(self)
252 }
253 fn to_object_ref(&self) -> ObjectRef {
254 ObjectRef::Hda(self)
255 }
256 fn to_warray(vec: Vec<Self>) -> WArray {
257 WArray::Hda(vec)
258 }
259}
260impl MessageType for WInfo {
261 fn to_object(self) -> Object {
262 Object::Inf(self)
263 }
264 fn to_object_ref(&self) -> ObjectRef {
265 ObjectRef::Inf(self)
266 }
267 fn to_warray(vec: Vec<Self>) -> WArray {
268 WArray::Inf(vec)
269 }
270}
271impl MessageType for WInfolist {
272 fn to_object(self) -> Object {
273 Object::Inl(self)
274 }
275 fn to_object_ref(&self) -> ObjectRef {
276 ObjectRef::Inl(self)
277 }
278 fn to_warray(vec: Vec<Self>) -> WArray {
279 WArray::Inl(vec)
280 }
281}
282impl MessageType for WArray {
283 fn to_object(self) -> Object {
284 Object::Arr(self)
285 }
286 fn to_object_ref(&self) -> ObjectRef {
287 ObjectRef::Arr(self)
288 }
289 fn to_warray(vec: Vec<Self>) -> WArray {
290 WArray::Arr(vec)
291 }
292}
293
294#[derive(Debug, PartialEq, Eq)]
297pub enum Identifier {
298 Client(Vec<u8>),
299 Event(Event),
300}
301
302#[derive(Debug, PartialEq, Eq)]
306pub enum Event {
307 BufferOpened,
308 BufferTypeChanged,
309 BufferMoved,
310 BufferMerged,
311 BufferUnmerged,
312 BufferHidden,
313 BufferUnhidden,
314 BufferRenamed,
315 BufferTitleChanged,
316 BufferLocalvarAdded,
317 BufferLocalvarChanged,
318 BufferLocalvarRemoved,
319 BufferClosing,
320 BufferCleared,
321 BufferLineAdded,
322 Nicklist,
323 NicklistDiff,
324 Pong,
325 Upgrade,
326 UpgradeEnded,
327}
328
329#[derive(Clone, Copy)]
331pub enum ObjectType {
332 Chr,
333 Int,
334 Lon,
335 Str,
336 Buf,
337 Ptr,
338 Tim,
339 Htb,
340 Hda,
341 Inf,
342 Inl,
343 Arr,
344}
345
346impl ObjectType {
347 pub fn new_warray(&self, capacity: usize) -> WArray {
348 match self {
349 Self::Chr => WArray::Chr(Vec::with_capacity(capacity)),
350 Self::Int => WArray::Int(Vec::with_capacity(capacity)),
351 Self::Lon => WArray::Lon(Vec::with_capacity(capacity)),
352 Self::Str => WArray::Str(Vec::with_capacity(capacity)),
353 Self::Buf => WArray::Buf(Vec::with_capacity(capacity)),
354 Self::Ptr => WArray::Ptr(Vec::with_capacity(capacity)),
355 Self::Tim => WArray::Tim(Vec::with_capacity(capacity)),
356 Self::Htb => WArray::Htb(Vec::with_capacity(capacity)),
357 Self::Hda => WArray::Hda(Vec::with_capacity(capacity)),
358 Self::Inf => WArray::Inf(Vec::with_capacity(capacity)),
359 Self::Inl => WArray::Inl(Vec::with_capacity(capacity)),
360 Self::Arr => WArray::Arr(Vec::with_capacity(capacity)),
361 }
362 }
363}
364
365#[derive(Debug, PartialEq, Eq, Hash, Clone)]
368pub enum Object {
369 Chr(WChar),
370 Int(WInteger),
371 Lon(WLongInteger),
372 Str(WString),
373 Buf(WBuffer),
374 Ptr(Pointer),
375 Tim(WTime),
376 Htb(WHashtable),
377 Hda(GenericHdata),
378 Inf(WInfo),
379 Inl(WInfolist),
380 Arr(WArray),
381 }
384
385impl Object {
386 fn vec_to_object_vec<T: MessageType>(v: Vec<T>) -> Vec<Self> {
387 v.into_iter().map(|o: T| o.to_object()).collect()
388 }
389
390 pub fn object_ref(&self) -> ObjectRef {
391 match self {
392 Self::Chr(v) => ObjectRef::Chr(v),
393 Self::Int(v) => ObjectRef::Int(v),
394 Self::Lon(v) => ObjectRef::Lon(v),
395 Self::Str(v) => ObjectRef::Str(v),
396 Self::Buf(v) => ObjectRef::Buf(v),
397 Self::Ptr(v) => ObjectRef::Ptr(v),
398 Self::Tim(v) => ObjectRef::Tim(v),
399 Self::Htb(v) => ObjectRef::Htb(v),
400 Self::Hda(v) => ObjectRef::Hda(v),
401 Self::Inf(v) => ObjectRef::Inf(v),
402 Self::Inl(v) => ObjectRef::Inl(v),
403 Self::Arr(v) => ObjectRef::Arr(v),
404 }
405 }
406}
407
408#[derive(Debug, PartialEq, Eq, Hash, Clone)]
409pub enum ObjectRef<'a> {
410 Chr(&'a WChar),
411 Int(&'a WInteger),
412 Lon(&'a WLongInteger),
413 Str(&'a WString),
414 Buf(&'a WBuffer),
415 Ptr(&'a Pointer),
416 Tim(&'a WTime),
417 Htb(&'a WHashtable),
418 Hda(&'a GenericHdata),
419 Inf(&'a WInfo),
420 Inl(&'a WInfolist),
421 Arr(&'a WArray),
422}
423
424impl<'a> ObjectRef<'a> {
425 fn vec_to_object_ref_vec<T: MessageType + 'a>(v: &'a [T]) -> Vec<Self> {
426 v.iter().map(|o: &T| o.to_object_ref()).collect()
427 }
428}
429
430#[derive(Debug, PartialEq, Eq, Hash, Clone)]
434pub enum WArray {
435 Chr(Vec<WChar>),
436 Int(Vec<WInteger>),
437 Lon(Vec<WLongInteger>),
438 Str(Vec<WString>),
439 Buf(Vec<WBuffer>),
440 Ptr(Vec<Pointer>),
441 Tim(Vec<WTime>),
442 Htb(Vec<WHashtable>),
443 Hda(Vec<GenericHdata>),
444 Inf(Vec<WInfo>),
445 Inl(Vec<WInfolist>),
446 Arr(Vec<WArray>),
447}
448
449#[macro_export]
465macro_rules! apply_to_warray {
466 ( $warray:expr, $function:expr ) => {
467 match $warray {
468 WArray::Chr(v) => $function(v),
469 WArray::Int(v) => $function(v),
470 WArray::Lon(v) => $function(v),
471 WArray::Str(v) => $function(v),
472 WArray::Buf(v) => $function(v),
473 WArray::Ptr(v) => $function(v),
474 WArray::Tim(v) => $function(v),
475 WArray::Htb(v) => $function(v),
476 WArray::Hda(v) => $function(v),
477 WArray::Inf(v) => $function(v),
478 WArray::Inl(v) => $function(v),
479 WArray::Arr(v) => $function(v),
480 }
481 };
482}
483
484#[macro_export]
489macro_rules! apply_to_warray_with {
490 ( $warray:expr, $data:expr, $function:expr ) => {
491 match $warray {
492 WArray::Chr(v) => $function(v, $data),
493 WArray::Int(v) => $function(v, $data),
494 WArray::Lon(v) => $function(v, $data),
495 WArray::Str(v) => $function(v, $data),
496 WArray::Buf(v) => $function(v, $data),
497 WArray::Ptr(v) => $function(v, $data),
498 WArray::Tim(v) => $function(v, $data),
499 WArray::Htb(v) => $function(v, $data),
500 WArray::Hda(v) => $function(v, $data),
501 WArray::Inf(v) => $function(v, $data),
502 WArray::Inl(v) => $function(v, $data),
503 WArray::Arr(v) => $function(v, $data),
504 }
505 };
506}
507
508impl WArray {
509 pub fn len(&self) -> usize {
510 apply_to_warray!(self, Vec::len)
511 }
512
513 pub fn is_empty(&self) -> bool {
514 apply_to_warray!(self, Vec::is_empty)
515 }
516
517 pub fn to_vec(self) -> Vec<Object> {
518 apply_to_warray!(self, Object::vec_to_object_vec)
519 }
520
521 pub fn to_ref_vec(&self) -> Vec<ObjectRef> {
522 apply_to_warray!(self, ObjectRef::vec_to_object_ref_vec)
523 }
524}
525
526pub fn to_hashmap<K, V>(keys: Vec<K>, vals: Vec<V>) -> HashMap<K, V>
528where
529 K: Eq + std::hash::Hash,
530{
531 keys.into_iter().zip(vals).collect::<HashMap<K, V>>()
532}