1#![feature(type_alias_impl_trait)]
24#![feature(unboxed_closures)]
25#![feature(buf_read_has_data_left)]
26
27pub mod cache;
28pub mod cli;
29pub mod core;
30pub mod json;
31pub mod log;
32pub mod maths;
33pub mod net;
34pub mod queue;
35pub mod scripting;
36pub mod search;
37pub mod strings;
38pub mod threading;
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use crate::cache::RUMCache;
44 use crate::search::rumtk_search::*;
45 use crate::strings::{RUMArrayConversions, RUMString, RUMStringConversions, StringUtils};
46 use compact_str::{format_compact, CompactString};
47 use serde::{Deserialize, Deserializer, Serialize, Serializer};
48 use serde_json::to_string;
49 use std::future::IntoFuture;
50 use std::sync::Arc;
51 use tokio::sync::RwLock;
52
53 #[test]
54 fn test_is_escaped_str() {
55 let input = "\r\n\'\\\"";
56 let expected = false;
57 let result = strings::is_escaped_str(input);
58 println!("Input: {} Expected: {} Got: {}", input, expected, result);
59 assert_eq!(
60 expected, result,
61 "Incorrect detection of unescaped string as escaped!!"
62 );
63 println!("Passed!")
64 }
65
66 #[test]
67 fn test_escaping_control() {
68 let input = "\r\n\'\"\\";
69 let expected = "\\r\\n\\'\\\"\\\\";
70 let result = strings::escape(input);
71 println!(
72 "Input: {} Expected: {} Got: {}",
73 input,
74 expected,
75 result.as_str()
76 );
77 assert_eq!(expected, result, "Incorrect string escaping!");
78 println!("Passed!")
79 }
80
81 #[test]
82 fn test_escaping_unicode() {
83 let input = "❤";
84 let expected = "\\u2764";
85 let result = strings::escape(input);
86 println!(
87 "Input: {} Expected: {} Got: {}",
88 input,
89 expected,
90 result.as_str()
91 );
92 assert_eq!(expected, result, "Incorrect string escaping!");
93 println!("Passed!")
94 }
95
96 #[test]
97 fn test_unescaping_unicode() {
98 let input = "❤";
99 let escaped = strings::escape(input);
100 let expected = "❤";
101 let result = RUMString::from_utf8(strings::unescape(escaped.as_str()).unwrap()).unwrap();
102 println!(
103 "Input: {} Expected: {} Got: {}",
104 input,
105 expected,
106 result.as_str()
107 );
108 assert_eq!(expected, result.as_str(), "Incorrect string unescaping!");
109 println!("Passed!")
110 }
111
112 #[test]
113 fn test_unescaping_string() {
114 let input = "I \\u2764 my wife!";
115 let expected = "I ❤ my wife!";
116 let result = strings::unescape_string(input).unwrap();
117 println!(
118 "Input: {} Expected: {} Got: {}",
119 input,
120 expected,
121 result.as_str()
122 );
123 assert_eq!(expected, result.as_str(), "Incorrect string unescaping!");
124 println!("Passed!")
125 }
126
127 #[test]
128 fn test_is_escaped_string() {
129 let input = "I \\u2764 my wife!";
130 let expected = true;
131 let result = strings::is_escaped_str(input);
132 println!("Input: {} Expected: {} Got: {}", input, expected, result);
133 assert_eq!(
134 expected, result,
135 "Escaped string detected as unescaped string!"
136 );
137 println!("Passed!")
138 }
139
140 #[test]
141 fn test_is_unescaped_string() {
142 let input = "I ❤ my wife!";
143 let expected = false;
144 let result = strings::is_escaped_str(input);
145 println!("Input: {} Expected: {} Got: {}", input, expected, result);
146 assert_eq!(
147 expected, result,
148 "Unescaped string detected as escaped string!"
149 );
150 println!("Passed!")
151 }
152
153 #[test]
154 fn test_unique_string() {
155 let input = "I❤mywife!";
156 assert!(input.is_unique(), "String was not detected as unique.");
157 }
158
159 #[test]
160 fn test_non_unique_string() {
161 let input = "I❤❤mywife!";
162 assert!(!input.is_unique(), "String was detected as unique.");
163 }
164
165 #[test]
166 fn test_escaping_string() {
167 let input = "I ❤ my wife!";
168 let expected = "I \\u2764 my wife!";
169 let result = strings::escape(input);
170 println!(
171 "Input: {} Expected: {} Got: {}",
172 input,
173 expected,
174 result.as_str()
175 );
176 assert_eq!(expected, result.as_str(), "Incorrect string escaping!");
177 println!("Passed!")
178 }
179
180 #[test]
181 fn test_autodecode_utf8() {
182 let input = "I ❤ my wife!";
183 let result = strings::try_decode(input.as_bytes());
184 println!(
185 "Input: {} Expected: {} Got: {}",
186 input,
187 input,
188 result.as_str()
189 );
190 assert_eq!(input, result, "Incorrect string decoding!");
191 println!("Passed!")
192 }
193
194 #[test]
195 fn test_autodecode_other() {
196 let input = "I ❤ my wife!";
198 let result = input;
199 println!("Input: {} Expected: {} Got: {}", input, input, result);
200 assert_eq!(input, result, "Incorrect string decoding!");
201 println!("Passed!")
202 }
203
204 #[test]
205 fn test_decode() {
206 let input = "I ❤ my wife!";
207 let result = strings::try_decode_with(input.as_bytes(), "utf-8");
208 println!(
209 "Input: {} Expected: {} Got: {}",
210 input,
211 input,
212 result.as_str()
213 );
214 assert_eq!(input, result, "Incorrect string decoding!");
215 println!("Passed!")
216 }
217
218 #[test]
219 fn test_rumcache_insertion() {
220 let mut cache: RUMCache<&str, CompactString> = RUMCache::with_capacity(5);
221 cache.insert("❤", CompactString::from("I ❤ my wife!"));
222 println!("Contents: {:#?}", &cache);
223 assert_eq!(cache.len(), 1, "Incorrect number of items in cache!");
224 println!("Passed!")
225 }
226
227 #[test]
228 fn test_search_string_letters() {
229 let input = "Hello World!";
230 let expr = r"\w";
231 let result = string_search(input, expr, "");
232 let expected: RUMString = RUMString::from("HelloWorld");
233 println!(
234 "Input: {:?} Expected: {:?} Got: {:?}",
235 input, expected, result
236 );
237 assert_eq!(expected, result, "String search results mismatch");
238 println!("Passed!")
239 }
240
241 #[test]
242 fn test_search_string_words() {
243 let input = "Hello World!";
244 let expr = r"\w+";
245 let result = string_search(input, expr, " ");
246 let expected: RUMString = RUMString::from("Hello World");
247 println!(
248 "Input: {:?} Expected: {:?} Got: {:?}",
249 input, expected, result
250 );
251 assert_eq!(expected, result, "String search results mismatch");
252 println!("Passed!")
253 }
254
255 #[test]
256 fn test_search_string_named_groups() {
257 let input = "Hello World!";
258 let expr = r"(?<hello>\w{5}) (?<world>\w{5})";
259 let result = string_search_named_captures(input, expr, "");
260 let expected: RUMString = RUMString::from("World");
261 println!(
262 "Input: {:?} Expected: {:?} Got: {:?}",
263 input, expected, result
264 );
265 assert_eq!(expected, result["world"], "String search results mismatch");
266 println!("Passed!")
267 }
268
269 #[test]
270 fn test_search_string_all_groups() {
271 let input = "Hello World!";
272 let expr = r"(?<hello>\w{5}) (?<world>\w{5})";
273 let result = string_search_all_captures(input, expr, "");
274 let expected: Vec<&str> = vec!["Hello", "World"];
275 println!(
276 "Input: {:?} Expected: {:?} Got: {:?}",
277 input, expected, result
278 );
279 assert_eq!(expected, result, "String search results mismatch");
280 println!("Passed!")
281 }
282
283 #[test]
285 fn test_default_num_threads() {
286 use num_cpus;
287 let threads = threading::threading_functions::get_default_system_thread_count();
288 assert_eq!(
289 threads >= num_cpus::get(),
290 true,
291 "Default thread count is incorrect! We got {}, but expected {}!",
292 threads,
293 num_cpus::get()
294 );
295 }
296
297 #[test]
298 fn test_execute_job() {
299 let rt = rumtk_init_threads!();
300 let expected = vec![1, 2, 3];
301 let task_processor = async |args: &SafeTaskArgs<i32>| -> TaskResult<i32> {
302 let owned_args = Arc::clone(args);
303 let lock_future = owned_args.read();
304 let locked_args = lock_future.await;
305 let mut results = TaskItems::<i32>::with_capacity(locked_args.len());
306 print!("Contents: ");
307 for arg in locked_args.iter() {
308 results.push(arg.clone());
309 println!("{} ", &arg);
310 }
311 Ok(results)
312 };
313 let locked_args = RwLock::new(expected.clone());
314 let task_args = SafeTaskArgs::<i32>::new(locked_args);
315 let task_result = rumtk_wait_on_task!(rt, task_processor, &task_args);
316 let result = task_result.unwrap();
317 assert_eq!(&result, &expected, "{}", format_compact!("Task processing returned a different result than expected! Expected {:?} \nResults {:?}", &expected, &result));
318 }
319
320 #[test]
321 fn test_execute_job_macros() {
322 let rt = rumtk_init_threads!();
323 let expected = vec![1, 2, 3];
324 let task_processor = async |args: &SafeTaskArgs<i32>| -> TaskResult<i32> {
325 let owned_args = Arc::clone(args);
326 let lock_future = owned_args.read();
327 let locked_args = lock_future.await;
328 let mut results = TaskItems::<i32>::with_capacity(locked_args.len());
329 print!("Contents: ");
330 for arg in locked_args.iter() {
331 results.push(arg.clone());
332 println!("{} ", &arg);
333 }
334 Ok(results)
335 };
336 let task_args = rumtk_create_task_args!(1, 2, 3);
337 let task_result = rumtk_wait_on_task!(rt, task_processor, &task_args);
338 let result = task_result.unwrap();
339 assert_eq!(&result, &expected, "{}", format_compact!("Task processing returned a different result than expected! Expected {:?} \nResults {:?}", &expected, &result));
340 }
341
342 #[test]
343 fn test_execute_job_macros_one_line() {
344 let rt = rumtk_init_threads!();
345 let expected = vec![1, 2, 3];
346 let result = rumtk_exec_task!(
347 async |args: &SafeTaskArgs<i32>| -> TaskResult<i32> {
348 let owned_args = Arc::clone(args);
349 let lock_future = owned_args.read();
350 let locked_args = lock_future.await;
351 let mut results = TaskItems::<i32>::with_capacity(locked_args.len());
352 print!("Contents: ");
353 for arg in locked_args.iter() {
354 results.push(arg.clone());
355 println!("{} ", &arg);
356 }
357 Ok(results)
358 },
359 vec![1, 2, 3]
360 )
361 .unwrap();
362 assert_eq!(&result, &expected, "{}", format_compact!("Task processing returned a different result than expected! Expected {:?} \nResults {:?}", &expected, &result));
363 }
364
365 #[test]
366 fn test_clamp_index_positive_index() {
367 let values = vec![1, 2, 3, 4];
368 let given_index = 3isize;
369 let max_size = values.len() as isize;
370 let index = clamp_index(&given_index, &max_size).unwrap();
371 assert_eq!(
372 index, 3,
373 "Index mismatch! Requested index {} but got {}",
374 &given_index, &index
375 );
376 assert_eq!(
377 values[index], 4,
378 "Value mismatch! Expected {} but got {}",
379 &values[3], &values[index]
380 );
381 }
382
383 #[test]
384 fn test_clamp_index_reverse_index() {
385 let values = vec![1, 2, 3, 4];
386 let given_index = -1isize;
387 let max_size = values.len() as isize;
388 let index = clamp_index(&given_index, &max_size).unwrap();
389 assert_eq!(
390 index, 4,
391 "Index mismatch! Requested index {} but got {}",
392 &given_index, &index
393 );
394 assert_eq!(
395 values[index - 1],
396 4,
397 "Value mismatch! Expected {} but got {}",
398 &values[3],
399 &values[index]
400 );
401 }
402
403 use crate::cli::cli_utils::print_license_notice;
405 use crate::core::clamp_index;
406 use crate::net::tcp::LOCALHOST;
407 use crate::threading::thread_primitives::{SafeTaskArgs, TaskItems, TaskResult};
408 use crate::threading::threading_functions::sleep;
409 use queue::queue::*;
410
411 #[test]
412 fn test_queue_data() {
413 let expected = vec![
414 RUMString::from("Hello"),
415 RUMString::from("World!"),
416 RUMString::from("Overcast"),
417 RUMString::from("and"),
418 RUMString::from("Sad"),
419 ];
420 let mut queue = TaskQueue::<RUMString>::new(&5).unwrap();
421 let locked_args = RwLock::new(expected.clone());
422 let task_args = SafeTaskArgs::<RUMString>::new(locked_args);
423 let processor = rumtk_create_task!(
424 async |args: &SafeTaskArgs<RUMString>| -> TaskResult<RUMString> {
425 let owned_args = Arc::clone(args);
426 let lock_future = owned_args.read();
427 let locked_args = lock_future.await;
428 let mut results = TaskItems::<RUMString>::with_capacity(locked_args.len());
429 print!("Contents: ");
430 for arg in locked_args.iter() {
431 print!("{} ", &arg);
432 results.push(RUMString::new(arg));
433 }
434 Ok(results)
435 },
436 task_args
437 );
438 queue.add_task::<_>(processor);
439 let results = queue.wait();
440 let mut result_data = Vec::<RUMString>::with_capacity(5);
441 for r in results {
442 for v in r.unwrap().iter() {
443 result_data.push(v.clone());
444 }
445 }
446 assert_eq!(result_data, expected, "Results do not match expected!");
447 }
448
449 #[test]
451 fn test_server_start() {
452 let mut server = match rumtk_create_server!("localhost", 0) {
453 Ok(server) => server,
454 Err(e) => panic!("Failed to create server because {}", e),
455 };
456 match server.start(false) {
457 Ok(_) => (),
458 Err(e) => panic!("Failed to start server because {}", e),
459 }
460 }
461
462 #[test]
463 fn test_server_send() {
464 let msg = RUMString::from("Hello World!");
465 let mut server = match rumtk_create_server!(LOCALHOST, 0, 1) {
466 Ok(server) => server,
467 Err(e) => panic!("Failed to create server because {}", e),
468 };
469 match server.start(false) {
470 Ok(_) => (),
471 Err(e) => panic!("Failed to start server because {}", e),
472 };
473 let address_info = server.get_address_info().unwrap();
474 let (ip, port) = rumtk_get_ip_port!(address_info);
475 println!("Sleeping");
476 rumtk_sleep!(1);
477 let mut client = match rumtk_connect!(port) {
478 Ok(client) => client,
479 Err(e) => panic!("Failed to create server because {}", e),
480 };
481 let client_id = client.get_address().unwrap();
482 rumtk_sleep!(1);
483 match server.send(&client_id, &msg.to_raw()) {
484 Ok(_) => (),
485 Err(e) => panic!("Server failed to send message because {}", e),
486 };
487 rumtk_sleep!(1);
488 let received_message = client.receive().unwrap();
489 assert_eq!(
490 &msg.to_raw(),
491 &received_message,
492 "{}",
493 format_compact!(
494 "Received message does not match sent message by server {:?}",
495 &received_message
496 )
497 );
498 }
499
500 #[test]
501 fn test_server_receive() {
502 let msg = RUMString::from("Hello World!");
503 let mut server = match rumtk_create_server!(LOCALHOST, 0) {
504 Ok(server) => server,
505 Err(e) => panic!("Failed to create server because {}", e),
506 };
507 match server.start(false) {
508 Ok(_) => (),
509 Err(e) => panic!("Failed to start server because {}", e),
510 };
511 let address_info = server.get_address_info().unwrap();
512 let (ip, port) = rumtk_get_ip_port!(address_info);
513 println!("Sleeping");
514 rumtk_sleep!(1);
515 let mut client = match rumtk_connect!(port) {
516 Ok(client) => client,
517 Err(e) => panic!("Failed to create server because {}", e),
518 };
519 match client.send(&msg.to_raw()) {
520 Ok(_) => (),
521 Err(e) => panic!("Failed to send message because {}", e),
522 };
523 rumtk_sleep!(1);
524 let client_id = client.get_address().expect("Failed to get client id");
525 let incoming_message = server.receive(&client_id).unwrap().to_rumstring();
526 println!("Received message => {:?}", &incoming_message);
527 assert_eq!(&incoming_message, msg, "Received message corruption!");
528 }
529
530 #[test]
531 fn test_server_get_clients() {
532 let mut server = match rumtk_create_server!(LOCALHOST, 0) {
533 Ok(server) => server,
534 Err(e) => panic!("Failed to create server because {}", e),
535 };
536 match server.start(false) {
537 Ok(_) => (),
538 Err(e) => panic!("Failed to start server because {}", e),
539 };
540 let address_info = server.get_address_info().unwrap();
541 let (ip, port) = rumtk_get_ip_port!(address_info);
542 println!("Sleeping");
543 rumtk_sleep!(1);
544 let mut client = match rumtk_connect!(port) {
545 Ok(client) => client,
546 Err(e) => panic!("Failed to create server because {}", e),
547 };
548 rumtk_sleep!(1);
549 let expected_client_id = client.get_address().expect("Failed to get client id");
550 let clients = server.get_client_ids();
551 let incoming_client_id = clients.get(0).expect("Expected client to have connected!");
552 println!("Connected client id => {}", &incoming_client_id);
553 assert_eq!(
554 &incoming_client_id, &expected_client_id,
555 "Connected client does not match the connecting client! Client id => {}",
556 &incoming_client_id
557 );
558 }
559
560 #[test]
561 fn test_server_stop() {
562 let msg = RUMString::from("Hello World!");
563 let mut server = match rumtk_create_server!("localhost", 0) {
564 Ok(server) => server,
565 Err(e) => panic!("Failed to create server because {}", e),
566 };
567 match server.start(false) {
568 Ok(_) => (),
569 Err(e) => panic!("Failed to start server because {}", e),
570 };
571 println!("Sleeping");
572 rumtk_sleep!(1);
573 match server.stop() {
574 Ok(_) => (),
575 Err(e) => panic!("Failed to stop server because {}", e),
576 };
577 }
578
579 #[test]
580 fn test_server_get_address_info() {
581 let msg = RUMString::from("Hello World!");
582 let mut server = match rumtk_create_server!("localhost", 0) {
583 Ok(server) => server,
584 Err(e) => panic!("Failed to create server because {}", e),
585 };
586 match server.start(false) {
587 Ok(_) => (),
588 Err(e) => panic!("Failed to start server because {}", e),
589 };
590 println!("Sleeping");
591 rumtk_sleep!(1);
592 match server.get_address_info() {
593 Some(addr) => println!("Server address info => {}", addr),
594 None => panic!("No address. Perhaps the server was never initialized?"),
595 };
596 }
597
598 #[test]
599 fn test_client_send() {
600 let msg = RUMString::from("Hello World!");
601 let mut server = match rumtk_create_server!(LOCALHOST, 0) {
602 Ok(server) => server,
603 Err(e) => panic!("Failed to create server because {}", e),
604 };
605 match server.start(false) {
606 Ok(_) => (),
607 Err(e) => panic!("Failed to start server because {}", e),
608 };
609 let address_info = server.get_address_info().unwrap();
610 let (ip, port) = rumtk_get_ip_port!(address_info);
611 println!("Sleeping");
612 rumtk_sleep!(1);
613 let mut client = match rumtk_connect!(port) {
614 Ok(client) => client,
615 Err(e) => panic!("Failed to create server because {}", e),
616 };
617 rumtk_sleep!(2);
618 match client.send(&msg.to_raw()) {
619 Ok(_) => (),
620 Err(e) => panic!("Failed to send message because {}", e),
621 };
622 rumtk_sleep!(1);
623 let clients = server.get_client_ids();
624 let incoming_client_id = clients.first().expect("Expected client to have connected!");
625 let mut received_message = server.receive(incoming_client_id).unwrap();
626 if received_message.is_empty() {
627 rumtk_sleep!(1);
628 received_message = server.receive(incoming_client_id).unwrap();
629 }
630 assert_eq!(
631 &msg.to_raw(),
632 &received_message,
633 "{}",
634 format_compact!(
635 "Received message does not match sent message by client {:?}",
636 &received_message
637 )
638 );
639 }
640
641 #[test]
644 fn test_serialize_json() {
645 #[derive(Serialize)]
646 struct MyStruct {
647 hello: RUMString,
648 }
649
650 let hw = MyStruct {
651 hello: RUMString::from("World"),
652 };
653 let hw_str = rumtk_serialize!(&hw, true).unwrap();
654
655 assert!(
656 !hw_str.is_empty(),
657 "Empty JSON string generated from the test struct!"
658 );
659 }
660
661 #[test]
662 fn test_deserialize_serde_json() {
663 use serde::{Deserialize, Deserializer, Serialize, Serializer};
664 use serde_json::{from_str, to_string};
665
666 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
667 struct MyStruct {
668 hello: RUMString,
669 }
670
671 let hw = MyStruct {
672 hello: RUMString::from("World"),
673 };
674 let hw_str = to_string(&hw).unwrap();
675 let new_hw: MyStruct = from_str(&hw_str).unwrap();
676
677 assert_eq!(
678 new_hw, hw,
679 "Deserialized JSON does not match the expected value!"
680 );
681 }
682
683 #[test]
684 fn test_deserialize_json() {
685 #[derive(Serialize, Deserialize, PartialEq)]
686 struct MyStruct {
687 hello: RUMString,
688 }
689
690 let hw = MyStruct {
691 hello: RUMString::from("World"),
692 };
693 let hw_str = rumtk_serialize!(&hw, true).unwrap();
694 let new_hw: MyStruct = rumtk_deserialize!(&hw_str).unwrap();
695
696 assert!(
697 new_hw == hw,
698 "Deserialized JSON does not match the expected value!"
699 );
700 }
701
702 #[test]
738 fn test_print_license_notice() {
739 print_license_notice("RUMTK", "2025", &vec!["Luis M. Santos, M.D."]);
740 }
741
742 }