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