mem_viewer/
lib.rs

1//! # Overview
2//! 
3//! `mem_viewer` is a Rust crate that provides a macro `view_mem!` to view the memory content of an arbitrary variable. It supports viewing memory content of different data types including integers, floating-point numbers, strings, pointers, vectors, boxed variables, and structs.
4//! 
5//! ## Usage
6//! 
7//! Add the following line to your `Cargo.toml` file:
8//! 
9//! ```toml
10//! [dependencies]
11//! mem_viewer = "0.3.0"
12//! ```
13//! 
14//! Then, in your Rust code, you can use the `view_mem!` macro to view the memory content of a variable. Here's an example:
15//! 
16//! ```rust
17//! use mem_viewer::*;
18//! 
19//! let my_str: &str = "πŸ¦€HelloπŸ˜ƒ";
20//! view_mem!(*my_str);
21//! ```
22//! 
23//! This will print the memory content of `my_var` to the console.
24//! 
25//! ## Example Output
26//! 
27//! ```none
28//! Name: *my_str
29//! Type: str
30//! Addr: 00007ff7f23fa4b8
31//! Size: 13 bytes
32//! Aloc: Likely Stack
33//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
34//! ----------------------Memory Content--------------------
35//!  00007ff7f23fa4b8 | f0  | 240 | 11110000 |  ...  | πŸ¦€ 
36//!  00007ff7f23fa4b9 | 9f  | 159 | 10011111 |  ...  | ... 
37//!  00007ff7f23fa4ba | a6  | 166 | 10100110 |  ...  | ... 
38//!  00007ff7f23fa4bb | 80  | 128 | 10000000 |  ...  | ... 
39//!  00007ff7f23fa4bc | 48  | 072 | 01001000 |   H   | Hell 
40//!  00007ff7f23fa4bd | 65  | 101 | 01100101 |   e   | ello 
41//!  00007ff7f23fa4be | 6c  | 108 | 01101100 |   l   | ... 
42//!  00007ff7f23fa4bf | 6c  | 108 | 01101100 |   l   | ... 
43//!  00007ff7f23fa4c0 | 6f  | 111 | 01101111 |   o   | ... 
44//!  00007ff7f23fa4c1 | f0  | 240 | 11110000 |  ...  | πŸ˜ƒ 
45//!  00007ff7f23fa4c2 | 9f  | 159 | 10011111 |  ...  | XXX
46//!  00007ff7f23fa4c3 | 98  | 152 | 10011000 |  ...  | XXX
47//!  00007ff7f23fa4c4 | 83  | 131 | 10000011 |  ...  | XXX
48//! ```
49//! 
50//! Read more for the macro usage: [https://docs.rs/mem_viewer/latest/mem_viewer/macro.view_mem.html](https://docs.rs/mem_viewer/latest/mem_viewer/macro.view_mem.html)
51//! 
52//! ## Safe Usage
53//! For safe mode, you can use the `safe_view_mem!` macro to view the memory content of a variable. Here's an example:
54//! ```rust
55//! use mem_viewer::*;
56//! 
57//! let my_str: &str = "πŸ¦€HelloπŸ˜ƒ";
58//! view_mem!(my_str);
59//! ```
60//! 
61//! ## Example Safe Output
62//! ```none
63//! Name         : my_str
64//! Type         : &str
65//! Addr         : 00007ff7f23fa4b8
66//! Size         : 16 bytes
67//! Aloc         : Likely Stack
68//! Container Ptr: 00000203f55753c0
69//! Container Len: 13
70//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
71//! ---------------------Container Content-------------------
72//!  00000203f55753c0 | f0  | 240 | 11110000 | ...   | πŸ¦€
73//!  00000203f55753c1 | 9f  | 159 | 10011111 | ...   | ...
74//!  00000203f55753c2 | a6  | 166 | 10100110 | ...   | ...
75//!  00000203f55753c3 | 80  | 128 | 10000000 | ...   | ...
76//!  00000203f55753c4 | 48  | 072 | 01001000 |  H    | Hell
77//!  00000203f55753c5 | 65  | 101 | 01100101 |  e    | ello
78//!  00000203f55753c6 | 6c  | 108 | 01101100 |  l    | ...
79//!  00000203f55753c7 | 6c  | 108 | 01101100 |  l    | ...
80//!  00000203f55753c8 | 6f  | 111 | 01101111 |  o    | ...
81//!  00000203f55753c9 | f0  | 240 | 11110000 | ...   | πŸ˜ƒ
82//!  00000203f55753ca | 9f  | 159 | 10011111 | ...   | XXX
83//!  00000203f55753cb | 98  | 152 | 10011000 | ...   | XXX
84//!  00000203f55753cc | 83  | 131 | 10000011 | ...   | XXX
85//! ```
86//! 
87//! Read more for safe usage: [https://docs.rs/mem_viewer/latest/mem_viewer/macro.safe_view_mem.html](https://docs.rs/mem_viewer/latest/mem_viewer/macro.safe_view_mem.html)
88//! 
89//! ## License
90//! 
91//! This crate is licensed under the MIT License.
92//! 
93//! ## Contributing
94//! 
95//! Contributions are welcome! If you find any issues or have any suggestions, please open an issue or submit a pull request on [GitHub](https://github.com/ikhwanperwira/mem_viewer).
96//! 
97//! # Unit Test Report
98//! 
99//! ## Code Test:
100//! ```rust
101//! 
102//! #[cfg(test)]
103//! mod tests {
104//!     use super::*;
105//! 
106//!     /// Display the memopry content of a u16 variable.
107//!     fn view_mem_u16(my_u16: u16) -> () {
108//!         // Unsafe test
109//!         view_mem!(my_u16);
110//! 
111//!         // Safe test
112//!         safe_view_mem!(&my_u16);
113//!     }
114//! 
115//!     /// Displays the memory content of a u64 variable.
116//!     fn view_mem_u64(my_u64: u64) -> () {
117//!         // Unsafe test
118//!         view_mem!(my_u64);
119//! 
120//!         // Safe test
121//!         safe_view_mem!(&my_u64);
122//!     }
123//! 
124//!     /// Displays the memory content of a f32 variable.
125//!     fn view_mem_f32(my_f32: f32) -> () {
126//!         // Unsafe test
127//!         view_mem!(my_f32);
128//! 
129//!         // Safe test
130//!         safe_view_mem!(&my_f32);
131//!     }
132//! 
133//!     /// Displays the memory content of a string variable.
134//!     fn view_mem_str(my_str: &str) -> () {
135//!         // Unsafe test
136//!         view_mem!(my_str); // Print address of the first character of the my_str
137//!         view_mem!(*my_str); // Print actual content of my_str
138//! 
139//!         // Safe test
140//!         safe_view_mem!(&my_str);
141//!         safe_view_mem!(my_str);
142//!     }
143//! 
144//!     /// Displays the memory content of a pointer.
145//!     fn view_mem_ptr<T>(my_ptr: *const T) -> () {
146//!         // Unsafe test
147//!         view_mem!(my_ptr);
148//!         unsafe { view_mem!(*my_ptr); }
149//! 
150//!         // Safe test
151//!         // Parameterized type is not supported for safe view.
152//!     }
153//! 
154//!     /// Displays the memory content of a vector variable.
155//!     fn view_mem_vec<T>(my_vec: Vec<T>) -> () {
156//!         // Unsafe test
157//!         view_mem!(my_vec);
158//!         view_mem!(*my_vec);
159//! 
160//!         // Safe test
161//!         // Parameterized type is not supported for safe view.
162//!     }
163//! 
164//!     /// Displays the memory content of a boxed variable.
165//!     fn view_mem_box<T>(my_box: Box<T>) -> () {
166//!         // Unsafe test
167//!         view_mem!(&my_box);
168//!         view_mem!(my_box);
169//!         view_mem!(*my_box);
170//! 
171//!         // Safe test
172//!         // Parameterized type is not supported for safe view.
173//!     }
174//! 
175//!     /// Displays the memory content of a vector of boxed variables.
176//!     fn view_mem_vec_of_box<T>(my_vec_of_box: Vec<Box<T>>) -> () {
177//!         // Unsafe test
178//!         view_mem!(my_vec_of_box);
179//!         view_mem!(*my_vec_of_box);
180//!         view_mem!(*my_vec_of_box[0]);
181//! 
182//!         // Safe test
183//!         // Parameterized type is not supported for safe view.
184//!     }
185//! 
186//!     /// Displays the memory content of a struct variable.
187//!     fn view_mem_struct<T>(my_struct: T) -> () {
188//!         // Unsafe test
189//!         view_mem!(&my_struct);
190//!         view_mem!(my_struct);
191//! 
192//!         // Parameterized type is not supported for safe view.
193//!     }
194//! 
195//!     fn view_mem_utf8(my_str: &str) -> () {
196//!         // Unsafe test
197//!         view_mem!(*my_str);
198//! 
199//!         // Safe test
200//!         safe_view_mem!(my_str);
201//!     }
202//! 
203//!     fn myfunc() {
204//!         println!("This is a function pointer.");
205//!     }
206//!      
207//!     struct MyStruct {
208//!         a: u8,
209//!         b: u16,
210//!         c: u32,
211//!     }
212//! 
213//!     #[derive(Serialize)]
214//!     struct MySerializedStruct {
215//!         a: u8,
216//!         b: u16,
217//!         c: u32,
218//!     }
219//! 
220//!     #[test]
221//!     fn u16_viewer() {
222//!         println!("This should print the memory of the holy number 69.\n");
223//!         assert_eq!(view_mem_u16(69), ());
224//!     }
225//! 
226//!     fn u64_viewer() {
227//!         println!("This should print the memory of the holy number 69.\n");
228//!         assert_eq!(view_mem_u64(69), ());
229//!     }
230//! 
231//!     #[test]
232//!     fn f32_viewer() {
233//!         println!("This should print the memory of pi in IEEE 754 representation, which is 0x4048f5c3.\n");
234//!         assert_eq!(view_mem_f32(3.14), ());
235//!     }
236//! 
237//!     #[test]
238//!     fn str_viewer() {
239//!         println!("This should print the memory of 'Hello' and its address.\n");
240//!         assert_eq!(view_mem_str("Hello"), ());
241//!     }
242//! 
243//!     #[test]
244//!     fn ptr_viewer() {
245//!         println!("This should print the memory of a pointer.\n");
246//!         let my_ptr: *const u8 = &69;
247//! 
248//!         // Safe test
249//!         println!("Currently pointer type is not supported by safe view memory.\n");
250//! 
251//!         // Unsafe test
252//!         assert_eq!(view_mem_ptr(my_ptr), ());
253//!     }
254//! 
255//!     #[test]
256//!     fn vec_viewer() {
257//!         println!("This should print the memory address of the vector and the memory of its elements.\n");
258//!         let my_vec: Vec<u8> = vec![69, 255, 254, 253, 70];
259//! 
260//!         // Safe test
261//!         safe_view_mem!(&my_vec);
262//! 
263//!         // Unsafe test
264//!         assert_eq!(view_mem_vec(my_vec), ());
265//!     }
266//! 
267//!     #[test]
268//!     fn box_viewer() {
269//!         println!("This should print the memory address of the box and the memory of its value.\n");
270//!         let my_box: Box<u8> = Box::new(69);
271//! 
272//!         // Safe test
273//!         safe_view_mem!(&my_box);
274//! 
275//! 
276//!         // Unsafe test
277//!         assert_eq!(view_mem_box(my_box), ());
278//!     }
279//! 
280//!     #[test]
281//!     fn vec_of_box_viewer() {
282//!         println!("This should print the memory address of the vector of boxes and the memory of its elements.\n");
283//!         let my_vec_of_box: Vec<Box<u8>> = vec![Box::new(69), Box::new(255), Box::new(254), Box::new(253), Box::new(70)];
284//! 
285//!         // Safe test
286//!         safe_view_mem!(&my_vec_of_box);
287//! 
288//!         // Unsafe test
289//!         assert_eq!(view_mem_vec_of_box(my_vec_of_box), ());
290//!     }
291//! 
292//!     #[test]
293//!     fn struct_viewer() {
294//!         println!("This should print the memory address of the struct and the memory of its fields.\n");
295//!         let my_struct = MyStruct {
296//!             a: 69,
297//!             b: 255,
298//!             c: 70,
299//!         };
300//! 
301//!         let my_serialized_struct = MySerializedStruct {
302//!             a: 69,
303//!             b: 255,
304//!             c: 70,
305//!         };
306//! 
307//!         // Safe test
308//!         safe_view_mem!(&my_serialized_struct);
309//! 
310//!         // Unsafe test
311//!         assert_eq!(view_mem_struct(my_struct), ());
312//!     }
313//! 
314//!     #[test]
315//!     fn utf8_viewer() {
316//!         println!("This should print the memory of fixed content of string between holy number in ASCII and UTF-8 emoji.\n");
317//!         assert_eq!(view_mem_utf8("πŸ˜ƒ6πŸ¦€9πŸ˜ƒ"), ());
318//!     }
319//! 
320//!     #[test]
321//!     fn functype_viewer() {
322//!         println!("This should print the memory of function pointer.\n");
323//! 
324//!         // Safe test
325//!         // Currently function pointer is not supported by safe view memory.
326//! 
327//!         // Unsafe test
328//!         view_mem!(&myfunc);
329//!     }
330//! 
331//! }
332//! ```
333//! 
334//! ## Output Test:
335//! ```none
336//! running 10 tests
337//! test tests::box_viewer ... ok
338//! test tests::f32_viewer ... ok
339//! test tests::functype_viewer ... ok
340//! test tests::ptr_viewer ... ok
341//! test tests::str_viewer ... ok
342//! test tests::struct_viewer ... ok
343//! test tests::u16_viewer ... ok
344//! test tests::utf8_viewer ... ok
345//! test tests::vec_of_box_viewer ... ok
346//! test tests::vec_viewer ... ok
347//! 
348//! successes:
349//! 
350//! ---- tests::box_viewer stdout ----
351//! This should print the memory address of the box and the memory of its value.
352//! 
353//! Name         : &my_box
354//! Type         : &alloc::boxed::Box<u8>
355//! Addr         : 00000038570fe198
356//! Size         : 8 bytes
357//! Aloc         : Likely Heap
358//! Container Ptr: 000001d943845210
359//! Container Len: 1
360//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
361//! ---------------------Container Content-------------------
362//!  000001d943845210 | 45  | 069 | 01000101 |  E    | XXX
363//! 
364//! Name: &my_box
365//! Type: &alloc::boxed::Box<u8>
366//! Addr: 00000038570fd548
367//! Size: 8 bytes
368//! Aloc: Likely Heap
369//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
370//! ----------------------Memory Content--------------------
371//!  00000038570fd7c0 | b8  | 184 | 10111000 |  ...  | ...
372//!  00000038570fd7c1 | d4  | 212 | 11010100 |  ...  | ...
373//!  00000038570fd7c2 | 0f  | 015 | 00001111 |  SI   | W8
374//!  00000038570fd7c3 | 57  | 087 | 01010111 |   W   | W8
375//!  00000038570fd7c4 | 38  | 056 | 00111000 |   8   | 8
376//!  00000038570fd7c5 | 00  | 000 | 00000000 |  NUL  | XXX
377//!  00000038570fd7c6 | 00  | 000 | 00000000 |  NUL  | XXX
378//!  00000038570fd7c7 | 00  | 000 | 00000000 |  NUL  | XXX
379//! 
380//! Name: my_box
381//! Type: alloc::boxed::Box<u8>
382//! Addr: 00000038570fd4b8
383//! Size: 8 bytes
384//! Aloc: Likely Heap
385//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
386//! ----------------------Memory Content--------------------
387//!  00000038570fd4b8 | c0  | 192 | 11000000 |  ...  | ...
388//!  00000038570fd4b9 | 52  | 082 | 01010010 |   R   | ...
389//!  00000038570fd4ba | 84  | 132 | 10000100 |  ...  | ...
390//!  00000038570fd4bb | 43  | 067 | 01000011 |   C   | ...
391//!  00000038570fd4bc | d9  | 217 | 11011001 |  ...  | ...
392//!  00000038570fd4bd | 01  | 001 | 00000001 |  SOH  | XXX
393//!  00000038570fd4be | 00  | 000 | 00000000 |  NUL  | XXX
394//!  00000038570fd4bf | 00  | 000 | 00000000 |  NUL  | XXX
395//! 
396//! Name: *my_box
397//! Type: u8
398//! Addr: 000001d9438452c0
399//! Size: 1 bytes
400//! Aloc: Likely Heap
401//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
402//! ----------------------Memory Content--------------------
403//!  000001d9438452c0 | 45  | 069 | 01000101 |   E   | XXX
404//! 
405//! 
406//! ---- tests::f32_viewer stdout ----
407//! This should print the memory of pi in IEEE 754 representation, which is 0x4048f5c3.
408//! 
409//! Name: my_f32
410//! Type: f32
411//! Addr: 00000038572fd6fc
412//! Size: 4 bytes
413//! Aloc: Likely Heap
414//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
415//! ----------------------Memory Content--------------------
416//!  00000038572fd6fc | c3  | 195 | 11000011 |  ...  | ...
417//!  00000038572fd6fd | f5  | 245 | 11110101 |  ...  | XXX
418//!  00000038572fd6fe | 48  | 072 | 01001000 |   H   | XXX
419//!  00000038572fd6ff | 40  | 064 | 01000000 |   @   | XXX
420//! 
421//! Name         : &my_f32
422//! Type         : &f32
423//! Addr         : 00000038572fd6fc
424//! Size         : 8 bytes
425//! Aloc         : Likely Heap
426//! Container Ptr: 000001d9438452c0
427//! Container Len: 4
428//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
429//! ---------------------Container Content-------------------
430//!  000001d9438452c0 | c3  | 195 | 11000011 | ...   | ...
431//!  000001d9438452c1 | f5  | 245 | 11110101 | ...   | XXX
432//!  000001d9438452c2 | 48  | 072 | 01001000 |  H    | XXX
433//!  000001d9438452c3 | 40  | 064 | 01000000 |  @    | XXX
434//! 
435//! 
436//! ---- tests::functype_viewer stdout ----
437//! This should print the memory of function pointer.
438//! 
439//! Name: &myfunc
440//! Type: &mem_viewer::tests::myfunc
441//! Addr: 00007ff62661f5b0
442//! Size: 8 bytes
443//! Aloc: Likely Stack
444//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
445//! ----------------------Memory Content--------------------
446//!  00007ff62661f5b0 | 38  | 056 | 00111000 |   8   | ...
447//!  00007ff62661f5b1 | ea  | 234 | 11101010 |  ...  | ...
448//!  00007ff62661f5b2 | 61  | 097 | 01100001 |   a   | ...
449//!  00007ff62661f5b3 | 26  | 038 | 00100110 |   &   | ...
450//!  00007ff62661f5b4 | f6  | 246 | 11110110 |  ...  | ...
451//!  00007ff62661f5b5 | 7f  | 127 | 01111111 |  DEL  | XXX
452//!  00007ff62661f5b6 | 00  | 000 | 00000000 |  NUL  | XXX
453//!  00007ff62661f5b7 | 00  | 000 | 00000000 |  NUL  | XXX
454//! 
455//! 
456//! ---- tests::ptr_viewer stdout ----
457//! This should print the memory of a pointer.
458//! 
459//! Currently pointer type is not supported by safe view memory.
460//! 
461//! Name: my_ptr
462//! Type: *const u8
463//! Addr: 00000038576fe8f8
464//! Size: 8 bytes
465//! Aloc: Likely Heap
466//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
467//! ----------------------Memory Content--------------------
468//!  00000038576fe8f8 | 10  | 016 | 00010000 |  DLE  | ...
469//!  00000038576fe8f9 | f1  | 241 | 11110001 |  ...  | ...
470//!  00000038576fe8fa | 61  | 097 | 01100001 |   a   | ...
471//!  00000038576fe8fb | 26  | 038 | 00100110 |   &   | ...
472//!  00000038576fe8fc | f6  | 246 | 11110110 |  ...  | ...
473//!  00000038576fe8fd | 7f  | 127 | 01111111 |  DEL  | XXX
474//!  00000038576fe8fe | 00  | 000 | 00000000 |  NUL  | XXX
475//!  00000038576fe8ff | 00  | 000 | 00000000 |  NUL  | XXX
476//! 
477//! Name: *my_ptr
478//! Type: u8
479//! Addr: 00007ff62661f110
480//! Size: 1 bytes
481//! Aloc: Likely Stack
482//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
483//! ----------------------Memory Content--------------------
484//!  00007ff62661f110 | 45  | 069 | 01000101 |   E   | XXX
485//! 
486//! 
487//! ---- tests::str_viewer stdout ----
488//! This should print the memory of 'Hello' and its address.
489//! 
490//! Name: my_str
491//! Type: &str
492//! Addr: 00000038578fc0b0
493//! Size: 16 bytes
494//! Aloc: Likely Heap
495//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
496//! ----------------------Memory Content--------------------
497//!  00000038578fc0b0 | b0  | 176 | 10110000 |  ...  | ...
498//!  00000038578fc0b1 | f0  | 240 | 11110000 |  ...  | ...
499//!  00000038578fc0b2 | 61  | 097 | 01100001 |   a   | ...
500//!  00000038578fc0b3 | 26  | 038 | 00100110 |   &   | ...
501//!  00000038578fc0b4 | f6  | 246 | 11110110 |  ...  | ...
502//!  00000038578fc0b5 | 7f  | 127 | 01111111 |  DEL  | ♣
503//!  00000038578fc0b6 | 00  | 000 | 00000000 |  NUL  | ♣
504//!  00000038578fc0b7 | 00  | 000 | 00000000 |  NUL  | ♣
505//!  00000038578fc0b8 | 05  | 005 | 00000101 |  ENQ  | ♣
506//!  00000038578fc0b9 | 00  | 000 | 00000000 |  NUL  |
507//!  00000038578fc0ba | 00  | 000 | 00000000 |  NUL  |
508//!  00000038578fc0bb | 00  | 000 | 00000000 |  NUL  |
509//!  00000038578fc0bc | 00  | 000 | 00000000 |  NUL  |
510//!  00000038578fc0bd | 00  | 000 | 00000000 |  NUL  | XXX
511//!  00000038578fc0be | 00  | 000 | 00000000 |  NUL  | XXX
512//!  00000038578fc0bf | 00  | 000 | 00000000 |  NUL  | XXX
513//! 
514//! Name: *my_str
515//! Type: str
516//! Addr: 00007ff62661f0b0
517//! Size: 5 bytes
518//! Aloc: Likely Stack
519//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
520//! ----------------------Memory Content--------------------
521//!  00007ff62661f0b0 | 48  | 072 | 01001000 |   H   | Hell
522//!  00007ff62661f0b1 | 65  | 101 | 01100101 |   e   | ello
523//!  00007ff62661f0b2 | 6c  | 108 | 01101100 |   l   | XXX
524//!  00007ff62661f0b3 | 6c  | 108 | 01101100 |   l   | XXX
525//!  00007ff62661f0b4 | 6f  | 111 | 01101111 |   o   | XXX
526//! 
527//! Name         : &my_str
528//! Type         : &&str
529//! Addr         : 00000038578fc0b0
530//! Size         : 8 bytes
531//! Aloc         : Likely Heap
532//! Container Ptr: 000001d943845390
533//! Container Len: 5
534//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
535//! ---------------------Container Content-------------------
536//!  000001d943845390 | 48  | 072 | 01001000 |  H    | Hell
537//!  000001d943845391 | 65  | 101 | 01100101 |  e    | ello
538//!  000001d943845392 | 6c  | 108 | 01101100 |  l    | XXX
539//!  000001d943845393 | 6c  | 108 | 01101100 |  l    | XXX
540//!  000001d943845394 | 6f  | 111 | 01101111 |  o    | XXX
541//! 
542//! Name         : my_str
543//! Type         : &str
544//! Addr         : 00007ff62661f0b0
545//! Size         : 16 bytes
546//! Aloc         : Likely Stack
547//! Container Ptr: 000001d9438451f0
548//! Container Len: 5
549//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
550//! ---------------------Container Content-------------------
551//!  000001d9438451f0 | 48  | 072 | 01001000 |  H    | Hell
552//!  000001d9438451f1 | 65  | 101 | 01100101 |  e    | ello
553//!  000001d9438451f2 | 6c  | 108 | 01101100 |  l    | XXX
554//!  000001d9438451f3 | 6c  | 108 | 01101100 |  l    | XXX
555//!  000001d9438451f4 | 6f  | 111 | 01101111 |  o    | XXX
556//! 
557//! 
558//! ---- tests::struct_viewer stdout ----
559//! This should print the memory address of the struct and the memory of its fields.
560//! 
561//! Name         : &my_serialized_struct
562//! Type         : &mem_viewer::tests::MySerializedStruct
563//! Addr         : 0000003857afe018
564//! Size         : 8 bytes
565//! Aloc         : Likely Heap
566//! Container Ptr: 000001d9438452d0
567//! Container Len: 7
568//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
569//! ---------------------Container Content-------------------
570//!  000001d9438452d0 | 45  | 069 | 01000101 |  E    | ...
571//!  000001d9438452d1 | ff  | 255 | 11111111 | ...   | ...
572//!  000001d9438452d2 | 00  | 000 | 00000000 | NUL   | F
573//!  000001d9438452d3 | 46  | 070 | 01000110 |  F    | F
574//!  000001d9438452d4 | 00  | 000 | 00000000 | NUL   | XXX
575//!  000001d9438452d5 | 00  | 000 | 00000000 | NUL   | XXX
576//!  000001d9438452d6 | 00  | 000 | 00000000 | NUL   | XXX
577//! 
578//! Name: &my_struct
579//! Type: &mem_viewer::tests::MyStruct
580//! Addr: 0000003857afd748
581//! Size: 8 bytes
582//! Aloc: Likely Heap
583//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
584//! ----------------------Memory Content--------------------
585//!  0000003857afd9c0 | b0  | 176 | 10110000 |  ...  | ...
586//!  0000003857afd9c1 | d6  | 214 | 11010110 |  ...  | Φ―W8
587//!  0000003857afd9c2 | af  | 175 | 10101111 |  ...  | ...
588//!  0000003857afd9c3 | 57  | 087 | 01010111 |   W   | W8
589//!  0000003857afd9c4 | 38  | 056 | 00111000 |   8   | 8
590//!  0000003857afd9c5 | 00  | 000 | 00000000 |  NUL  | XXX
591//!  0000003857afd9c6 | 00  | 000 | 00000000 |  NUL  | XXX
592//!  0000003857afd9c7 | 00  | 000 | 00000000 |  NUL  | XXX
593//! 
594//! Name: my_struct
595//! Type: mem_viewer::tests::MyStruct
596//! Addr: 0000003857afd6b0
597//! Size: 8 bytes
598//! Aloc: Likely Heap
599//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
600//! ----------------------Memory Content--------------------
601//!  0000003857afd6b0 | 46  | 070 | 01000110 |   F   | F
602//!  0000003857afd6b1 | 00  | 000 | 00000000 |  NUL  | ...
603//!  0000003857afd6b2 | 00  | 000 | 00000000 |  NUL  | ...
604//!  0000003857afd6b3 | 00  | 000 | 00000000 |  NUL  | ...
605//!  0000003857afd6b4 | ff  | 255 | 11111111 |  ...  | ...
606//!  0000003857afd6b5 | 00  | 000 | 00000000 |  NUL  | XXX
607//!  0000003857afd6b6 | 45  | 069 | 01000101 |   E   | XXX
608//!  0000003857afd6b7 | 00  | 000 | 00000000 |  NUL  | XXX
609//! 
610//! 
611//! ---- tests::u16_viewer stdout ----
612//! This should print the memory of the holy number 69.
613//! 
614//! Name: my_u16
615//! Type: u16
616//! Addr: 00000038570fdb9e
617//! Size: 2 bytes
618//! Aloc: Likely Heap
619//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
620//! ----------------------Memory Content--------------------
621//!  00000038570fdb9e | 45  | 069 | 01000101 |   E   | XXX 
622//!  00000038570fdb9f | 00  | 000 | 00000000 |  NUL  | XXX
623//! 
624//! Name         : &my_u16
625//! Type         : &u16
626//! Addr         : 00000038570fdb9e
627//! Size         : 8 bytes
628//! Aloc         : Likely Heap
629//! Container Ptr: 000001d943845380
630//! Container Len: 2
631//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
632//! ---------------------Container Content-------------------
633//!  000001d943845380 | 45  | 069 | 01000101 |  E    | XXX
634//!  000001d943845381 | 00  | 000 | 00000000 | NUL   | XXX
635//! 
636//! 
637//! ---- tests::utf8_viewer stdout ----
638//! This should print the memory of fixed content of string between holy number in ASCII and UTF-8 emoji.
639//! 
640//! Name: *my_str
641//! Type: str
642//! Addr: 00007ff62661f520
643//! Size: 14 bytes
644//! Aloc: Likely Stack
645//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
646//! ----------------------Memory Content--------------------
647//!  00007ff62661f520 | f0  | 240 | 11110000 |  ...  | πŸ˜ƒ
648//!  00007ff62661f521 | 9f  | 159 | 10011111 |  ...  | ...
649//!  00007ff62661f522 | 98  | 152 | 10011000 |  ...  | ...
650//!  00007ff62661f523 | 83  | 131 | 10000011 |  ...  | ...
651//!  00007ff62661f524 | 36  | 054 | 00110110 |   6   | ...
652//!  00007ff62661f525 | f0  | 240 | 11110000 |  ...  | πŸ¦€
653//!  00007ff62661f526 | 9f  | 159 | 10011111 |  ...  | ...
654//!  00007ff62661f527 | a6  | 166 | 10100110 |  ...  | ...
655//!  00007ff62661f528 | 80  | 128 | 10000000 |  ...  | ...
656//!  00007ff62661f529 | 39  | 057 | 00111001 |   9   | ...
657//!  00007ff62661f52a | f0  | 240 | 11110000 |  ...  | πŸ˜ƒ
658//!  00007ff62661f52b | 9f  | 159 | 10011111 |  ...  | XXX
659//!  00007ff62661f52c | 98  | 152 | 10011000 |  ...  | XXX
660//!  00007ff62661f52d | 83  | 131 | 10000011 |  ...  | XXX
661//! 
662//! Name         : my_str
663//! Type         : &str
664//! Addr         : 00007ff62661f520
665//! Size         : 16 bytes
666//! Aloc         : Likely Stack
667//! Container Ptr: 000001d943848570
668//! Container Len: 14
669//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
670//! ---------------------Container Content-------------------
671//!  000001d943848570 | f0  | 240 | 11110000 | ...   | πŸ˜ƒ
672//!  000001d943848571 | 9f  | 159 | 10011111 | ...   | ...
673//!  000001d943848572 | 98  | 152 | 10011000 | ...   | ...
674//!  000001d943848573 | 83  | 131 | 10000011 | ...   | ...
675//!  000001d943848574 | 36  | 054 | 00110110 |  6    | ...
676//!  000001d943848575 | f0  | 240 | 11110000 | ...   | πŸ¦€
677//!  000001d943848576 | 9f  | 159 | 10011111 | ...   | ...
678//!  000001d943848577 | a6  | 166 | 10100110 | ...   | ...
679//!  000001d943848578 | 80  | 128 | 10000000 | ...   | ...
680//!  000001d943848579 | 39  | 057 | 00111001 |  9    | ...
681//!  000001d94384857a | f0  | 240 | 11110000 | ...   | πŸ˜ƒ
682//!  000001d94384857b | 9f  | 159 | 10011111 | ...   | XXX
683//!  000001d94384857c | 98  | 152 | 10011000 | ...   | XXX
684//!  000001d94384857d | 83  | 131 | 10000011 | ...   | XXX
685//! 
686//! 
687//! ---- tests::vec_of_box_viewer stdout ----
688//! This should print the memory address of the vector of boxes and the memory of its elements.
689//! 
690//! Name         : &my_vec_of_box
691//! Type         : &alloc::vec::Vec<alloc::boxed::Box<u8>>
692//! Addr         : 00000038570fdae0
693//! Size         : 8 bytes
694//! Aloc         : Likely Heap
695//! Container Ptr: 000001d943845360
696//! Container Len: 5
697//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
698//! ---------------------Container Content-------------------
699//!  000001d943845360 | 45  | 069 | 01000101 |  E    | ...
700//!  000001d943845361 | ff  | 255 | 11111111 | ...   | ...
701//!  000001d943845362 | fe  | 254 | 11111110 | ...   | XXX
702//!  000001d943845363 | fd  | 253 | 11111101 | ...   | XXX
703//!  000001d943845364 | 46  | 070 | 01000110 |  F    | XXX
704//! 
705//! Name: my_vec_of_box
706//! Type: alloc::vec::Vec<alloc::boxed::Box<u8>>
707//! Addr: 00000038570fe910
708//! Size: 24 bytes
709//! Aloc: Likely Heap
710//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
711//! ----------------------Memory Content--------------------
712//!  00000038570fe910 | 05  | 005 | 00000101 |  ENQ  | ♣
713//!  00000038570fe911 | 00  | 000 | 00000000 |  NUL  |
714//!  00000038570fe912 | 00  | 000 | 00000000 |  NUL  |
715//!  00000038570fe913 | 00  | 000 | 00000000 |  NUL  |
716//!  00000038570fe914 | 00  | 000 | 00000000 |  NUL  |
717//!  00000038570fe915 | 00  | 000 | 00000000 |  NUL  | ...
718//!  00000038570fe916 | 00  | 000 | 00000000 |  NUL  | ...
719//!  00000038570fe917 | 00  | 000 | 00000000 |  NUL  | ...
720//!  00000038570fe918 | a0  | 160 | 10100000 |  ...  | ...
721//!  00000038570fe919 | 26  | 038 | 00100110 |   &   | ...
722//!  00000038570fe91a | 84  | 132 | 10000100 |  ...  | ...
723//!  00000038570fe91b | 43  | 067 | 01000011 |   C   | ...
724//!  00000038570fe91c | d9  | 217 | 11011001 |  ...  | ...
725//!  00000038570fe91d | 01  | 001 | 00000001 |  SOH  | β˜Ίβ™£
726//!  00000038570fe91e | 00  | 000 | 00000000 |  NUL  | ♣
727//!  00000038570fe91f | 00  | 000 | 00000000 |  NUL  | ♣
728//!  00000038570fe920 | 05  | 005 | 00000101 |  ENQ  | ♣
729//!  00000038570fe921 | 00  | 000 | 00000000 |  NUL  |
730//!  00000038570fe922 | 00  | 000 | 00000000 |  NUL  |
731//!  00000038570fe923 | 00  | 000 | 00000000 |  NUL  |
732//!  00000038570fe924 | 00  | 000 | 00000000 |  NUL  |
733//!  00000038570fe925 | 00  | 000 | 00000000 |  NUL  | XXX
734//!  00000038570fe926 | 00  | 000 | 00000000 |  NUL  | XXX
735//!  00000038570fe927 | 00  | 000 | 00000000 |  NUL  | XXX
736//! 
737//! Name: *my_vec_of_box
738//! Type: [alloc::boxed::Box<u8>]
739//! Addr: 000001d9438426a0
740//! Size: 40 bytes
741//! Aloc: Likely Heap
742//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
743//! ----------------------Memory Content--------------------
744//!  000001d9438426a0 | 90  | 144 | 10010000 |  ...  | ...
745//!  000001d9438426a1 | 52  | 082 | 01010010 |   R   | ...
746//!  000001d9438426a2 | 84  | 132 | 10000100 |  ...  | ...
747//!  000001d9438426a3 | 43  | 067 | 01000011 |   C   | ...
748//!  000001d9438426a4 | d9  | 217 | 11011001 |  ...  | ...
749//!  000001d9438426a5 | 01  | 001 | 00000001 |  SOH  | ☺0
750//!  000001d9438426a6 | 00  | 000 | 00000000 |  NUL  | 0R
751//!  000001d9438426a7 | 00  | 000 | 00000000 |  NUL  | ...
752//!  000001d9438426a8 | 30  | 048 | 00110000 |   0   | ...
753//!  000001d9438426a9 | 52  | 082 | 01010010 |   R   | ...
754//!  000001d9438426aa | 84  | 132 | 10000100 |  ...  | ...
755//!  000001d9438426ab | 43  | 067 | 01000011 |   C   | ...
756//!  000001d9438426ac | d9  | 217 | 11011001 |  ...  | ...
757//!  000001d9438426ad | 01  | 001 | 00000001 |  SOH  | ...
758//!  000001d9438426ae | 00  | 000 | 00000000 |  NUL  | ...
759//!  000001d9438426af | 00  | 000 | 00000000 |  NUL  | ...
760//!  000001d9438426b0 | a0  | 160 | 10100000 |  ...  | ...
761//!  000001d9438426b1 | 52  | 082 | 01010010 |   R   | ...
762//!  000001d9438426b2 | 84  | 132 | 10000100 |  ...  | ...
763//!  000001d9438426b3 | 43  | 067 | 01000011 |   C   | ...
764//!  000001d9438426b4 | d9  | 217 | 11011001 |  ...  | ...
765//!  000001d9438426b5 | 01  | 001 | 00000001 |  SOH  | β˜Ίβ–Ί
766//!  000001d9438426b6 | 00  | 000 | 00000000 |  NUL  | β–ΊS
767//!  000001d9438426b7 | 00  | 000 | 00000000 |  NUL  | ...
768//!  000001d9438426b8 | 10  | 016 | 00010000 |  DLE  | ...
769//!  000001d9438426b9 | 53  | 083 | 01010011 |   S   | ...
770//!  000001d9438426ba | 84  | 132 | 10000100 |  ...  | ...
771//!  000001d9438426bb | 43  | 067 | 01000011 |   C   | ...
772//!  000001d9438426bc | d9  | 217 | 11011001 |  ...  | ...
773//!  000001d9438426bd | 01  | 001 | 00000001 |  SOH  | ...
774//!  000001d9438426be | 00  | 000 | 00000000 |  NUL  | ...
775//!  000001d9438426bf | 00  | 000 | 00000000 |  NUL  | ...
776//!  000001d9438426c0 | f0  | 240 | 11110000 |  ...  | ...
777//!  000001d9438426c1 | 51  | 081 | 01010001 |   Q   | ...
778//!  000001d9438426c2 | 84  | 132 | 10000100 |  ...  | ...
779//!  000001d9438426c3 | 43  | 067 | 01000011 |   C   | ...
780//!  000001d9438426c4 | d9  | 217 | 11011001 |  ...  | ...
781//!  000001d9438426c5 | 01  | 001 | 00000001 |  SOH  | XXX
782//!  000001d9438426c6 | 00  | 000 | 00000000 |  NUL  | XXX
783//!  000001d9438426c7 | 00  | 000 | 00000000 |  NUL  | XXX
784//! 
785//! Name: *my_vec_of_box[0]
786//! Type: u8
787//! Addr: 000001d943845290
788//! Size: 1 bytes
789//! Aloc: Likely Heap
790//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
791//! ----------------------Memory Content--------------------
792//!  000001d943845290 | 45  | 069 | 01000101 |   E   | XXX
793//! 
794//! 
795//! ---- tests::vec_viewer stdout ----
796//! This should print the memory address of the vector and the memory of its elements.
797//! 
798//! Name         : &my_vec
799//! Type         : &alloc::vec::Vec<u8>
800//! Addr         : 00000038570fe028
801//! Size         : 8 bytes
802//! Aloc         : Likely Heap
803//! Container Ptr: 000001d943845290
804//! Container Len: 5
805//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
806//! ---------------------Container Content-------------------
807//!  000001d943845290 | 45  | 069 | 01000101 |  E    | ...
808//!  000001d943845291 | ff  | 255 | 11111111 | ...   | ...
809//!  000001d943845292 | fe  | 254 | 11111110 | ...   | XXX
810//!  000001d943845293 | fd  | 253 | 11111101 | ...   | XXX
811//!  000001d943845294 | 46  | 070 | 01000110 |  F    | XXX
812//! 
813//! Name: my_vec
814//! Type: alloc::vec::Vec<u8>
815//! Addr: 00000038570fee30
816//! Size: 24 bytes
817//! Aloc: Likely Heap
818//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
819//! ----------------------Memory Content--------------------
820//!  00000038570fee30 | 05  | 005 | 00000101 |  ENQ  | ♣
821//!  00000038570fee31 | 00  | 000 | 00000000 |  NUL  |
822//!  00000038570fee32 | 00  | 000 | 00000000 |  NUL  |
823//!  00000038570fee33 | 00  | 000 | 00000000 |  NUL  |
824//!  00000038570fee34 | 00  | 000 | 00000000 |  NUL  |
825//!  00000038570fee35 | 00  | 000 | 00000000 |  NUL  | β–Ί
826//!  00000038570fee36 | 00  | 000 | 00000000 |  NUL  | β–ΊR
827//!  00000038570fee37 | 00  | 000 | 00000000 |  NUL  | ...
828//!  00000038570fee38 | 10  | 016 | 00010000 |  DLE  | ...
829//!  00000038570fee39 | 52  | 082 | 01010010 |   R   | ... 
830//!  00000038570fee3a | 84  | 132 | 10000100 |  ...  | ...
831//!  00000038570fee3b | 43  | 067 | 01000011 |   C   | ...
832//!  00000038570fee3c | d9  | 217 | 11011001 |  ...  | ...
833//!  00000038570fee3d | 01  | 001 | 00000001 |  SOH  | β˜Ίβ™£
834//!  00000038570fee3e | 00  | 000 | 00000000 |  NUL  | ♣
835//!  00000038570fee3f | 00  | 000 | 00000000 |  NUL  | ♣
836//!  00000038570fee40 | 05  | 005 | 00000101 |  ENQ  | ♣
837//!  00000038570fee41 | 00  | 000 | 00000000 |  NUL  |
838//!  00000038570fee42 | 00  | 000 | 00000000 |  NUL  |
839//!  00000038570fee43 | 00  | 000 | 00000000 |  NUL  |
840//!  00000038570fee44 | 00  | 000 | 00000000 |  NUL  |
841//!  00000038570fee45 | 00  | 000 | 00000000 |  NUL  | XXX
842//!  00000038570fee46 | 00  | 000 | 00000000 |  NUL  | XXX
843//!  00000038570fee47 | 00  | 000 | 00000000 |  NUL  | XXX
844//! 
845//! Name: *my_vec
846//! Type: [u8]
847//! Addr: 000001d943845210
848//! Size: 5 bytes
849//! Aloc: Likely Heap
850//!      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
851//! ----------------------Memory Content--------------------
852//!  000001d943845210 | 45  | 069 | 01000101 |   E   | ...
853//!  000001d943845211 | ff  | 255 | 11111111 |  ...  | ...
854//!  000001d943845212 | fe  | 254 | 11111110 |  ...  | XXX
855//!  000001d943845213 | fd  | 253 | 11111101 |  ...  | XXX
856//!  000001d943845214 | 46  | 070 | 01000110 |   F   | XXX
857//! 
858//! 
859//! 
860//! successes:
861//!     tests::box_viewer
862//!     tests::f32_viewer
863//!     tests::functype_viewer
864//!     tests::ptr_viewer
865//!     tests::str_viewer
866//!     tests::struct_viewer
867//!     tests::u16_viewer
868//!     tests::utf8_viewer
869//!     tests::vec_of_box_viewer
870//!     tests::vec_viewer
871//! 
872//! test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
873//! ```
874//! 
875
876#![allow(dead_code)]
877
878pub use bincode::serialize_into;
879pub use serde::Serialize;
880
881#[macro_export]
882/// Macro to view the memory content of almost any arbitrary variable in safe way
883/// 
884/// It's safe because it's isolated on container with serializing into `Vec<u8>` by `serde`. Hence, the address and size displayed is not accurate and actually it's virtual address of the container instead of reported by OS.
885/// 
886/// It supports viewing memory content of different data types including integers, floating-point numbers, strings, vectors, boxed variables, and structs. Except pointer.
887/// 
888/// For struct, it's mandatory to add `#[derive(Serialize)]` to the struct definition.
889/// 
890/// For example:
891/// ```rust
892/// #[derive(Serialize)]
893/// struct MyStruct {
894///    a: i32,
895///    b: f32,
896/// }
897/// ```
898/// 
899/// # Argument
900/// 
901/// * `&var` - The variable whose memory content needs to be viewed.
902/// 
903/// # Example
904/// 
905/// ```rust
906/// use mem_viewer::*;
907/// 
908/// let my_str: &str = "πŸ¦€HelloπŸ˜ƒ";
909/// view_mem!(my_str);
910/// ```
911/// 
912/// # Output
913/// 
914/// ```none
915/// Name         : my_str
916/// Type         : &str
917/// Addr         : 00007ff7f23fa4b8
918/// Size         : 16 bytes
919/// Aloc         : Likely Stack
920/// Container Ptr: 00000203f55753c0
921/// Container Len: 13
922///      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
923/// ---------------------Container Content-------------------
924///  00000203f55753c0 | f0  | 240 | 11110000 | ...   | πŸ¦€
925///  00000203f55753c1 | 9f  | 159 | 10011111 | ...   | ...
926///  00000203f55753c2 | a6  | 166 | 10100110 | ...   | ...
927///  00000203f55753c3 | 80  | 128 | 10000000 | ...   | ...
928///  00000203f55753c4 | 48  | 072 | 01001000 |  H    | Hell
929///  00000203f55753c5 | 65  | 101 | 01100101 |  e    | ello
930///  00000203f55753c6 | 6c  | 108 | 01101100 |  l    | ...
931///  00000203f55753c7 | 6c  | 108 | 01101100 |  l    | ...
932///  00000203f55753c8 | 6f  | 111 | 01101111 |  o    | ...
933///  00000203f55753c9 | f0  | 240 | 11110000 | ...   | πŸ˜ƒ
934///  00000203f55753ca | 9f  | 159 | 10011111 | ...   | XXX
935///  00000203f55753cb | 98  | 152 | 10011000 | ...   | XXX
936///  00000203f55753cc | 83  | 131 | 10000011 | ...   | XXX
937/// ```
938macro_rules! safe_view_mem  {
939	($var: expr) => {
940        let size = std::mem::size_of_val(&$var);
941
942		// Print variable metadata
943		println!("Name         : {}", stringify!($var));
944		println!("Type         : {}", _get_type_of($var));
945        println!("Addr         : {:016x}", $var as *const _ as *const u8 as usize);
946		println!("Size         : {} bytes", size);
947
948        if format!("{:016x}", $var as *const _ as *const u8 as usize).contains("07f") {
949            // tell user that this addres probably in stack
950            println!("Aloc         : Likely Stack");
951        } else {
952            println!("Aloc         : Likely Heap");
953        }
954
955		// Isolate on container
956		let mut container: Vec<u8> = Vec::new();
957		serialize_into(&mut container, $var).unwrap();
958		// println!("Container Raw : {:?}", container);
959		if container.len() >= 8 && container.len() != size {
960			 // If not same, then there is header of serializer with size 8 bytes, exclude it!
961			container = (&container[8..]).to_vec();
962		}
963
964		// Print container metadata
965		// println!("Container Val : {:?}", container);
966        println!("Container Ptr: {:016x}", container.as_ptr() as usize);
967		println!("Container Len: {}", container.len());
968
969		// Print container content
970        println!("     Address      | Hex | Dec |    Bin   | ASCII | UTF-8");
971        println!("---------------------Container Content-------------------");
972		// Iterate over Vec<u8>
973		for (index, byte) in container.iter().enumerate() {
974			let addr = byte as *const u8 as usize;
975			let hex = format!("{:02x}", byte);
976			let dec = format!("{:03}", byte);
977			let bin = format!("{:08b}", byte);
978			let ascii = if byte.is_ascii_graphic() {
979				format!(" {} ", *byte as char)
980			} else {
981				match byte {
982							0   => "NUL",
983							1   => "SOH",
984							2   => "STX",
985							3   => "ETX",
986							4   => "EOT",
987							5   => "ENQ",
988							6   => "ACK",
989							7   => "BEL",
990							8   => "BS ",
991							9   => "HT ",
992							10  => "LF ",
993							11  => "VT ",
994							12  => "FF ",
995							13  => "CR ",
996							14  => "SO ",
997							15  => "SI ",
998							16  => "DLE",
999							17  => "DC1",
1000							18  => "DC2",
1001							19  => "DC3",
1002							20  => "DC4",
1003							21  => "NAK",
1004							22  => "SYN",
1005							23  => "ETB",
1006							24  => "CAN",
1007							25  => "EM ",
1008							26  => "SUB",
1009							27  => "ESC",
1010							28  => "FS ",
1011							29  => "GS ",
1012							30  => "RS ",
1013							31  => "US ",
1014							32  => "SPC",
1015							127 => "DEL",
1016							_   => "...",
1017					}.to_string()
1018			};
1019            // Get forward 4 byte for utf8 read from byte
1020            let diff = (container.len() - index) as isize;
1021			let utf8 = if diff >= 4 {
1022                let utf8 = std::str::from_utf8(&container[index..index+4]);
1023                if utf8.is_ok() {
1024                    utf8.unwrap().to_string()
1025                } else {
1026                    "...".to_string()
1027                }
1028            } else {
1029                "XXX".to_string()
1030            };
1031
1032			println!(" {:016x} | {}  | {} | {} | {}   | {}", addr, hex, dec, bin, ascii, utf8);
1033		};
1034
1035		println!();
1036	}
1037	}
1038
1039
1040#[macro_export]
1041/// Macro to view the memory content of an arbitrary variable.
1042/// 
1043/// It supports viewing memory content of different data types including integers, floating-point numbers, strings, pointers, vectors, boxed variables, and structs.
1044/// 
1045/// This is more **unsafe** than safe_view_mem! macro, because it directly reads the memory content of the variable.
1046/// 
1047/// As a result, it can be used to view the memory content of a pointer.
1048/// 
1049/// You can dereference a variable as many as you want as long compiler allows it, of course this is **unsafe** operation.
1050///
1051/// # Argument
1052///
1053/// * `var` - The variable whose memory content needs to be viewed.
1054///
1055/// # Example
1056///
1057/// ```rust
1058/// use mem_viewer::*;
1059/// 
1060/// let my_str: &str = "πŸ¦€HelloπŸ˜ƒ";
1061/// view_mem!(*my_str);
1062/// ```
1063/// 
1064/// # Output
1065/// 
1066/// ```none
1067/// Name: *my_str
1068/// Type: str
1069/// Addr: 00007ff7f23fa4b8
1070/// Size: 13 bytes
1071/// Aloc: Likely Stack
1072///      Address      | Hex | Dec |    Bin   | ASCII | UTF-8
1073/// ----------------------Memory Content--------------------
1074///  00007ff7f23fa4b8 | f0  | 240 | 11110000 |  ...  | πŸ¦€ 
1075///  00007ff7f23fa4b9 | 9f  | 159 | 10011111 |  ...  | ... 
1076///  00007ff7f23fa4ba | a6  | 166 | 10100110 |  ...  | ... 
1077///  00007ff7f23fa4bb | 80  | 128 | 10000000 |  ...  | ... 
1078///  00007ff7f23fa4bc | 48  | 072 | 01001000 |   H   | Hell 
1079///  00007ff7f23fa4bd | 65  | 101 | 01100101 |   e   | ello 
1080///  00007ff7f23fa4be | 6c  | 108 | 01101100 |   l   | ... 
1081///  00007ff7f23fa4bf | 6c  | 108 | 01101100 |   l   | ... 
1082///  00007ff7f23fa4c0 | 6f  | 111 | 01101111 |   o   | ... 
1083///  00007ff7f23fa4c1 | f0  | 240 | 11110000 |  ...  | πŸ˜ƒ 
1084///  00007ff7f23fa4c2 | 9f  | 159 | 10011111 |  ...  | XXX
1085///  00007ff7f23fa4c3 | 98  | 152 | 10011000 |  ...  | XXX
1086///  00007ff7f23fa4c4 | 83  | 131 | 10000011 |  ...  | XXX
1087/// ```
1088macro_rules! view_mem {
1089    ($var: expr) => {
1090        // Get the size of the variable
1091        // let size = std::mem::size_of_val(&$var);
1092
1093        // Print metadata of var: var_name, size, type, separated by a new line for each meta
1094        println!("Name: {}", stringify!($var));
1095        _print_type_of(&$var);
1096        println!("Addr: {:016x}", &$var as *const _ as *const u8 as usize);
1097        println!("Size: {} bytes", std::mem::size_of_val(&$var));
1098
1099        if format!("{:016x}", &$var as *const _ as *const u8 as usize).contains("007f") {
1100            // tell user that this addres probably in stack
1101            println!("Aloc: Likely Stack");
1102        } else {
1103            println!("Aloc: Likely Heap");
1104        }
1105
1106
1107        _show_memory_content(&$var as *const _ as *const u8, std::mem::size_of_val(&$var));
1108    };
1109}
1110
1111/// Returns the type of a variable as a string.
1112/// 
1113/// (This is supposed to be private usage of safe_view_mem! macro usage.)
1114/// 
1115/// # Argument
1116/// 
1117/// * `_: T` - The variable whose type needs to be returned.
1118pub fn _get_type_of<T>(_: T) -> &'static str {
1119	std::any::type_name::<T>()
1120}
1121
1122/// Prints the type of a variable.
1123///
1124/// (This is supposed to be private usage for unsafe view_mem! macro usage.)
1125/// 
1126/// # Argument
1127///
1128/// * `_: T` - The variable whose type needs to be printed.
1129pub fn _print_type_of<T>(_: T) {
1130    let type_name = &std::any::type_name::<T>()[1..]; // Remove `&` at first character
1131    println!("Type: {}", type_name);
1132}
1133
1134/// Displays the memory content of a given memory address.
1135///
1136/// 
1137/// (This is supposed to be private usage for unsafe view_mem! macro usage.)
1138/// 
1139/// # Arguments
1140///
1141/// * `src_ptr` - The memory address to start displaying from.
1142/// * `len` - The number of bytes to display.
1143pub fn _show_memory_content(src_ptr: *const u8, len: usize) { // This supposed to be private usage.
1144    // Display the memory and its value for every byte from src_ptr to src_ptr + len
1145
1146    let mut ptr: *const u8 = src_ptr;
1147    let end: *const u8 = unsafe { src_ptr.add(len) };
1148
1149    println!("     Address      | Hex | Dec |    Bin   | ASCII | UTF-8");
1150    println!("----------------------Memory Content--------------------");
1151    while ptr < end {
1152        let byte = unsafe {*ptr};
1153
1154        let ascii = if byte.is_ascii_graphic() {
1155            format!(" {} ", byte as char)
1156        } else {
1157            match byte {
1158                0   => "NUL",
1159                1   => "SOH",
1160                2   => "STX",
1161                3   => "ETX",
1162                4   => "EOT",
1163                5   => "ENQ",
1164                6   => "ACK",
1165                7   => "BEL",
1166                8   => "BS ",
1167                9   => "HT ",
1168                10  => "LF ",
1169                11  => "VT ",
1170                12  => "FF ",
1171                13  => "CR ",
1172                14  => "SO ",
1173                15  => "SI ",
1174                16  => "DLE",
1175                17  => "DC1",
1176                18  => "DC2",
1177                19  => "DC3",
1178                20  => "DC4",
1179                21  => "NAK",
1180                22  => "SYN",
1181                23  => "ETB",
1182                24  => "CAN",
1183                25  => "EM ",
1184                26  => "SUB",
1185                27  => "ESC",
1186                28  => "FS ",
1187                29  => "GS ",
1188                30  => "RS ",
1189                31  => "US ",
1190                32  => "SPC",
1191                127 => "DEL",
1192                _   => "...",
1193            }.to_string()
1194        };
1195
1196        // Get current difference between ptr and len
1197        let diff: isize = (end as usize - ptr as usize) as isize;
1198
1199        let utf8 = if diff >= 4 {
1200            let slice = unsafe { std::slice::from_raw_parts(ptr, 4) };
1201            match std::str::from_utf8(slice) {
1202                Ok(s) => format!("{}", s),
1203                Err(_) => "...".to_string(),
1204            }
1205        } else {
1206            "XXX".to_string()
1207        };
1208
1209        println!(" {:016x} | {:02x}  | {:03} | {:08b} |  {}  | {} ", ptr as usize, byte as u8, byte as u8, byte as u8, ascii, utf8);
1210
1211        ptr = unsafe { ptr.add(1) };
1212    }
1213
1214    println!();
1215}
1216
1217#[cfg(test)]
1218mod tests {
1219    use super::*;
1220
1221    /// Display the memopry content of a u16 variable.
1222    fn view_mem_u16(my_u16: u16) -> () {
1223        // Unsafe test
1224        view_mem!(my_u16);
1225
1226        // Safe test
1227        safe_view_mem!(&my_u16);
1228    }
1229
1230    /// Displays the memory content of a u64 variable.
1231    fn view_mem_u64(my_u64: u64) -> () {
1232        // Unsafe test
1233        view_mem!(my_u64);
1234
1235        // Safe test
1236        safe_view_mem!(&my_u64);
1237    }
1238
1239    /// Displays the memory content of a f32 variable.
1240    fn view_mem_f32(my_f32: f32) -> () {
1241        // Unsafe test
1242        view_mem!(my_f32);
1243
1244        // Safe test
1245        safe_view_mem!(&my_f32);
1246    }
1247
1248    /// Displays the memory content of a string variable.
1249    fn view_mem_str(my_str: &str) -> () {
1250        // Unsafe test
1251        view_mem!(my_str); // Print address of the first character of the my_str
1252        view_mem!(*my_str); // Print actual content of my_str
1253
1254        // Safe test
1255        safe_view_mem!(&my_str);
1256        safe_view_mem!(my_str);
1257    }
1258
1259    /// Displays the memory content of a pointer.
1260    fn view_mem_ptr<T>(my_ptr: *const T) -> () {
1261        // Unsafe test
1262        view_mem!(my_ptr);
1263        unsafe { view_mem!(*my_ptr); }
1264
1265        // Safe test
1266        // Parameterized type is not supported for safe view.
1267    }
1268
1269    /// Displays the memory content of a vector variable.
1270    fn view_mem_vec<T>(my_vec: Vec<T>) -> () {
1271        // Unsafe test
1272        view_mem!(my_vec);
1273        view_mem!(*my_vec);
1274
1275        // Safe test
1276        // Parameterized type is not supported for safe view.
1277    }
1278
1279    /// Displays the memory content of a boxed variable.
1280    fn view_mem_box<T>(my_box: Box<T>) -> () {
1281        // Unsafe test
1282        view_mem!(&my_box);
1283        view_mem!(my_box);
1284        view_mem!(*my_box);
1285
1286        // Safe test
1287        // Parameterized type is not supported for safe view.
1288    }
1289
1290    /// Displays the memory content of a vector of boxed variables.
1291    fn view_mem_vec_of_box<T>(my_vec_of_box: Vec<Box<T>>) -> () {
1292        // Unsafe test
1293        view_mem!(my_vec_of_box);
1294        view_mem!(*my_vec_of_box);
1295        view_mem!(*my_vec_of_box[0]);
1296
1297        // Safe test
1298        // Parameterized type is not supported for safe view.
1299    }
1300
1301    /// Displays the memory content of a struct variable.
1302    fn view_mem_struct<T>(my_struct: T) -> () {
1303        // Unsafe test
1304        view_mem!(&my_struct);
1305        view_mem!(my_struct);
1306
1307        // Parameterized type is not supported for safe view.
1308    }
1309
1310    fn view_mem_utf8(my_str: &str) -> () {
1311        // Unsafe test
1312        view_mem!(*my_str);
1313
1314        // Safe test
1315        safe_view_mem!(my_str);
1316    }
1317
1318    fn myfunc() {
1319        println!("This is a function pointer.");
1320    }
1321     
1322    struct MyStruct {
1323        a: u8,
1324        b: u16,
1325        c: u32,
1326    }
1327
1328    #[derive(Serialize)]
1329    struct MySerializedStruct {
1330        a: u8,
1331        b: u16,
1332        c: u32,
1333    }
1334
1335    #[test]
1336    fn u16_viewer() {
1337        println!("This should print the memory of the holy number 69.\n");
1338        assert_eq!(view_mem_u16(69), ());
1339    }
1340
1341    fn u64_viewer() {
1342        println!("This should print the memory of the holy number 69.\n");
1343        assert_eq!(view_mem_u64(69), ());
1344    }
1345
1346    #[test]
1347    fn f32_viewer() {
1348        println!("This should print the memory of pi in IEEE 754 representation, which is 0x4048f5c3.\n");
1349        assert_eq!(view_mem_f32(3.14), ());
1350    }
1351
1352    #[test]
1353    fn str_viewer() {
1354        println!("This should print the memory of 'Hello' and its address.\n");
1355        assert_eq!(view_mem_str("Hello"), ());
1356    }
1357
1358    #[test]
1359    fn ptr_viewer() {
1360        println!("This should print the memory of a pointer.\n");
1361        let my_ptr: *const u8 = &69;
1362
1363        // Safe test
1364        println!("Currently pointer type is not supported by safe view memory.\n");
1365
1366        // Unsafe test
1367        assert_eq!(view_mem_ptr(my_ptr), ());
1368    }
1369
1370    #[test]
1371    fn vec_viewer() {
1372        println!("This should print the memory address of the vector and the memory of its elements.\n");
1373        let my_vec: Vec<u8> = vec![69, 255, 254, 253, 70];
1374
1375        // Safe test
1376        safe_view_mem!(&my_vec);
1377
1378        // Unsafe test
1379        assert_eq!(view_mem_vec(my_vec), ());
1380    }
1381
1382    #[test]
1383    fn box_viewer() {
1384        println!("This should print the memory address of the box and the memory of its value.\n");
1385        let my_box: Box<u8> = Box::new(69);
1386
1387        // Safe test
1388        safe_view_mem!(&my_box);
1389
1390
1391        // Unsafe test
1392        assert_eq!(view_mem_box(my_box), ());
1393    }
1394
1395    #[test]
1396    fn vec_of_box_viewer() {
1397        println!("This should print the memory address of the vector of boxes and the memory of its elements.\n");
1398        let my_vec_of_box: Vec<Box<u8>> = vec![Box::new(69), Box::new(255), Box::new(254), Box::new(253), Box::new(70)];
1399
1400        // Safe test
1401        safe_view_mem!(&my_vec_of_box);
1402
1403        // Unsafe test
1404        assert_eq!(view_mem_vec_of_box(my_vec_of_box), ());
1405    }
1406
1407    #[test]
1408    fn struct_viewer() {
1409        println!("This should print the memory address of the struct and the memory of its fields.\n");
1410        let my_struct = MyStruct {
1411            a: 69,
1412            b: 255,
1413            c: 70,
1414        };
1415
1416        let my_serialized_struct = MySerializedStruct {
1417            a: 69,
1418            b: 255,
1419            c: 70,
1420        };
1421
1422        // Safe test
1423        safe_view_mem!(&my_serialized_struct);
1424
1425        // Unsafe test
1426        assert_eq!(view_mem_struct(my_struct), ());
1427    }
1428
1429    #[test]
1430    fn utf8_viewer() {
1431        println!("This should print the memory of fixed content of string between holy number in ASCII and UTF-8 emoji.\n");
1432        assert_eq!(view_mem_utf8("πŸ˜ƒ6πŸ¦€9πŸ˜ƒ"), ());
1433    }
1434
1435    #[test]
1436    fn functype_viewer() {
1437        println!("This should print the memory of function pointer.\n");
1438
1439        // Safe test
1440        // Currently function pointer is not supported by safe view memory.
1441
1442        // Unsafe test
1443        view_mem!(&myfunc);
1444    }
1445
1446}
1447