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