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