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