ak_macros/lib.rs
1/// ```
2/// use akp_macros::akp;
3/// /// or
4/// use ak_macros::*
5/// akp!("Hello World");
6/// ```
7#[macro_export]
8macro_rules! akp {
9 ($($arg:tt)*) => {
10 println!($($arg)*);
11 };
12}
13///```
14/// ///input_prompt can get input from user
15/// ///example
16/// use apk_macros::input_prompt
17/// /// or
18/// use ak_macros::*
19///
20///let user_name = input_prompt!("Enter Your Name:");
21/// akp!("User Name is:{}",user_name);
22/// ```
23#[macro_export]
24macro_rules! input_prompt {
25 ($prompt:expr) => {{
26 use std::io::{stdin, stdout, Write};
27 print!("{}", $prompt);
28 let _ = stdout().flush();
29 let mut input = String::new();
30 stdin().read_line(&mut input).expect("Failed to read input");
31 input.trim().to_string() // Changed parse() to to_string() to handle strings
32 }};
33}
34
35///```
36/// /// this macro can remove any folder at your PC
37/// /// this macro take one value this value is folder Path
38/// /// example
39/// remove_folder!("/home/ak/Desktop/new_Folder/");
40/// /// when macro remove folder the macro will print Done...! at terminal
41/// ```
42#[macro_export]
43macro_rules! remove_folder {
44 ($path:expr) => {
45 use std::fs;
46 if let Err(e) = fs::remove_dir($path) {
47 eprintln!("Error removing: {}", e);
48 } else {
49 println!("Done...!");
50 }
51 };
52}
53
54///```
55/// /// this macro can remove any file at your PC
56/// /// this macro take one value this value is folder Path
57/// /// example
58/// remove_file!("/home/ak/Desktop/new_file/");
59/// /// when macro remove file the macro will print Done...! at terminal
60/// ```
61#[macro_export]
62macro_rules! remove_file {
63 ($path:expr) => {
64 if let Err(e) = fs::remove_file($path) {
65 eprintln!("Error removing: {}", e);
66 } else {
67 println!("Done...!");
68 }
69 };
70}
71
72///```
73/// /// remove_all_folders macro can remove all folders and file at the path you will set it
74/// remove_all_folders!("/home/ak/Desktop/new_Folder/");
75/// ```
76#[macro_export]
77macro_rules! remove_all_folders {
78 ($path:expr) => {
79 if let Err(e) = fs::remove_dir_all($path) {
80 eprintln!("Error removing: {}", e);
81 } else {
82 println!("Done...!");
83 }
84 };
85}
86
87///```
88/// ///use_loop macro can create a loop
89/// ///this macro take Five values
90/// /// 1 - if you want to do event at loop set True else set False
91/// /// 2 - start-Number
92/// /// 3 - End-Number
93/// /// 4 - variable for loop
94/// /// 5 - the method
95/// /// you should type true at first value to method working
96/// /// example
97/// use_loop!(true, 0, 100, i, akp!("{}", i));
98/// /// dont do this
99/// use_loop!(false, 0, 100, i, akp!("{}", i)); /// Syntax Error
100/// ```
101#[macro_export]
102macro_rules! use_loop {
103 ($should_execute:expr, $start_number:expr, $end_number:expr, $theVar:ident, $the_method:expr) => {
104 for $theVar in $start_number..$end_number {
105 if $should_execute {
106 $the_method;
107 }
108 }
109 };
110}
111
112///```
113/// /// if_cond macro do if condition method
114/// /// the macro take 4 values
115/// /// 1 - import the value you want to do event about him
116/// /// 2 - do condition
117/// /// 3 - if event
118/// /// 4 - else event
119/// /// for example
120/// let my_name = "ak-macros";
121/// if_cond!(my_name,
122/// my_name == "ak-macros",
123/// akp!("Hello package"),
124/// akp!("Oh No, this is not best crate...!")
125/// )
126/// /// let's do simple app with AK-Macros
127///
128/// let my_name = input_prompt!("Enter this Crate Name: ");
129/// if_cond!(my_name,
130/// my_name == "ak-macros",
131/// akp!("Hello devs...!"),
132/// akp!("Try Again...")
133///);
134///
135/// ///let's use the use_loop macro at this app
136///let my_name = input_prompt!("Enter this Crate Name: ");
137///if_cond!(
138///my_name,
139///my_name == "ak-macros",
140///use_loop!(true, 0, 100, i, akp!("{} - hello guys", i)),
141/// akp!("Try Again...")
142///);
143/// // if you Type at input => ak-macros the use loop will start working
144/// ```
145#[macro_export]
146macro_rules! if_cond {
147 ($var:expr, $condition:expr, $first_method:expr, $last_method:expr) => {
148 if $condition {
149 $first_method
150 } else {
151 $last_method
152 }
153 };
154 ($name:expr, $cond:expr, $action:expr) => {{
155 if $cond {
156 $action;
157 }
158 }};
159 ($name:expr, $($cond:expr => $action:expr),*) => {{
160 $(if $cond { $action; })*
161 }};
162 ($name:expr, $($cond:expr => $action:expr),* $(,)?) => {{
163 $(if $cond { $action; })*
164 }};
165}
166
167///```
168/// /// terminal macro its like a terminal at your OS
169/// /// the macro can do any command at you OS
170/// /// to use the macro you should type two Values
171/// /// 1 - your OS command
172/// /// if you use windows the OS command is CMD
173/// /// if you use Linux the OS command is sh
174/// /// for example
175/// terminal!("sh", "mkdir ak-macros_App");
176/// /// if you want type more command you must end the command with ;
177/// ///
178///terminal!(
179///"sh",
180///"
181///cd '/home/ak/Desktop/' ;
182///mkdir ak-macros_App ;
183///cd ak-macros_App ;
184///touch new_file
185///"
186///);
187/// ```
188#[macro_export]
189macro_rules! terminal {
190 ($lang:expr, $command:expr) => {{
191 use std::fs::File;
192 use std::io::Write;
193 use std::process::Command;
194
195 let output = Command::new($lang)
196 .arg("-c")
197 .arg($command)
198 .output()
199 .expect("failed to execute process");
200
201 let output_str = String::from_utf8_lossy(&output.stdout);
202 let command_output = output_str.trim().to_string();
203
204 command_output // Returning the command output
205 }};
206}
207
208///```
209/// this_OS!(); ///macro can know your operating system Name
210/// /// you can use it at any conditions
211/// /// example
212/// akp!("My operating system is :{}",this_OS!());
213/// /// this command will print Your OS
214///
215/// ```
216#[macro_export]
217macro_rules! this_OS {
218 () => {
219 std::env::consts::OS
220 };
221}
222///```
223/// /// use_rand macro, this macro can generate a Random Number
224/// /// to use the macro you should add rand at cargo.toml
225/// /// the macro take 3 values
226/// /// 1 - variable
227/// /// 2 - point number
228/// /// 3 - the Method
229/// /// you can type to values only [1,3]
230/// /// and the default value for point number is // i32
231/// /// example
232///use_rand!(my_float, {
233///println!("Random float: {}", my_float);
234///});
235/// /// or
236///use_rand!(my_float,f64,{
237///println!("Random float: {}", my_float);
238///});
239/// ```
240#[macro_export]
241macro_rules! use_rand {
242 ($var:ident, {$($method:tt)*}) => {
243 use rand::prelude::*;
244
245 let mut rng = rand::thread_rng();
246 let $var: i32 = rng.gen();
247 $($method)*
248 };
249
250 ($var:ident, $kind:ty, {$($method:tt)*}) => {
251 use rand::prelude::*;
252
253 let mut rng = rand::thread_rng();
254 let $var: $kind = rng.gen();
255 $($method)*
256 };
257}
258
259///```
260/// /// use_fetch it's a fetch api macro
261/// /// to use it add
262/// /// 1 - reqwest
263/// /// 2 - tokio
264/// /// 3 - serde
265/// /// 4 - serde_json
266/// /// at Cargo.toml
267/// /// usage
268/// /// the macro take two values
269/// use_fetch!("api",HTTP_Request);
270/// /// example
271/// #[tokio::main]
272///async fn main() -> Result<(), Box<dyn std::error::Error>> {
273// Call the macro with API endpoint and HTTP method
274///use_fetch!("https://fakestoreapi.com/products/", GET);
275
276// Return Ok(()) as the result
277/// Ok(())
278///}
279///
280///
281/// ```
282#[macro_export]
283macro_rules! use_fetch {
284 ($api:expr, $method:ident) => {{
285 extern crate reqwest;
286 use std::collections::HashMap;
287 let api = $api.to_string();
288 let method = stringify!($method).to_string();
289
290 let response = reqwest::Client::new()
291 .request(reqwest::Method::from_bytes(method.as_bytes())?, &api)
292 .send()
293 .await?;
294
295 let resp_json = response
296 .json::<Vec<HashMap<String, serde_json::Value>>>()
297 .await?;
298
299 for item in resp_json {
300 println!("{:#?}", item);
301 }
302
303 Ok(()) as Result<(), Box<dyn std::error::Error>>
304 }};
305}
306
307///```
308/// use_zip!(); /// macro can extract the ZIP files
309/// /// to use this macro you should add zip-extract at Cargo.toml
310/// /// the macro take two values
311/// use_zip!("ZIP_PAth","Path_for_EXtract_Files");
312///
313/// /// example
314/// fn main() -> Result<(), Box<dyn std::error::Error>> {
315///use_zip!(
316///"Desktop/folder.zip",
317/// "Desktop/Extract_Folder"
318///);
319
320/// /// Return Ok(()) as the result
321///Ok(())
322///}
323
324/// ```
325///
326
327#[macro_export]
328macro_rules! use_zip {
329 ($zip_file_location:expr, $extract_file_location:expr) => {{
330 use ak_macros::use_zip;
331 use std::fs::File;
332 use std::io::Cursor;
333 use std::io::{self, Read};
334 use std::path::PathBuf;
335 use zip_extract::ZipExtractError;
336 let input_value = $zip_file_location;
337 let target_path = $extract_file_location;
338
339 let file = std::fs::File::open(input_value.trim())?;
340 let mut bytes = Vec::new();
341 file.take(1024 * 1024 * 100) // Limit the file size to 100 MB for safety
342 .read_to_end(&mut bytes)?;
343
344 let target = std::path::PathBuf::from(target_path.trim());
345
346 let cursor = std::io::Cursor::new(bytes);
347
348 match zip_extract::extract(cursor, &target, false) {
349 Ok(_) => {
350 println!("Extraction successful!");
351 Ok(())
352 }
353 Err(err) => match err {
354 zip_extract::ZipExtractError::Io(io_err) => Err(io_err),
355 other_err => Err(std::io::Error::new(
356 std::io::ErrorKind::Other,
357 format!("Zip extraction error: {:?}", other_err),
358 )),
359 },
360 }
361 }};
362}
363
364///```
365/// this_month!(); /// Macro to show month
366/// /// example
367/// let month = this_month!();
368/// akp!("month is: {}",month);
369/// ```
370#[macro_export]
371macro_rules! this_month {
372 () => {{
373 use std::time::{SystemTime, UNIX_EPOCH};
374 let now = SystemTime::now();
375 let since_epoch = now.duration_since(UNIX_EPOCH).expect("Time went backwards");
376 let seconds_since_epoch = since_epoch.as_secs();
377 let remaining_seconds = seconds_since_epoch % (365 * 24 * 60 * 60);
378 let month = remaining_seconds / (30 * 24 * 60 * 60) + 1;
379 month
380 }};
381}
382
383///```
384/// this_year!(); /// Macro to show Year
385/// /// example
386/// let year = this_year!();
387/// akp!("Year is: {}",year);
388/// ```
389#[macro_export]
390macro_rules! this_year {
391 () => {{
392 use std::time::{SystemTime, UNIX_EPOCH};
393 let now = SystemTime::now();
394 let since_epoch = now.duration_since(UNIX_EPOCH).expect("Time went backwards");
395 let seconds_since_epoch = since_epoch.as_secs();
396 let _ = seconds_since_epoch % (365 * 24 * 60 * 60);
397 let year = 1970 + seconds_since_epoch / (365 * 24 * 60 * 60);
398 year
399 }};
400}
401// /```
402// / /// open_web macro can open a url at browser
403// / ///the macro take one value this value is the URL Link
404// / ///example
405// / open_Web!("https://askander.vercel.app");
406// / ```
407#[macro_export]
408macro_rules! open_Web {
409 ($website_url:expr) => {{
410 let url = $website_url;
411
412 let result = if cfg!(target_os = "windows") {
413 std::process::Command::new("cmd")
414 .arg("/C")
415 .arg("start")
416 .arg(url)
417 .spawn()
418 } else if cfg!(target_os = "macos") {
419 std::process::Command::new("open").arg(url).spawn()
420 } else {
421 std::process::Command::new("xdg-open").arg(url).spawn()
422 };
423
424 // Check if the command executed successfully
425 match result {
426 Ok(_) => println!("Successfully opened website."),
427 Err(e) => eprintln!("Failed to open website: {}", e),
428 }
429 }};
430}
431
432///```
433/// /// macro can convert the string from lowerCase to UpperCase
434/// use_upper_case!(name);
435/// println!("{}",name);
436/// ```
437#[macro_export]
438macro_rules! use_upper_case {
439 ($input:ident) => {
440 $input = $input.to_uppercase();
441 };
442}
443
444///```
445/// /// macro can convert the string from upperCase to lowerCase
446/// use_lower_case!(name);
447/// println!("{}",name);
448/// ```
449#[macro_export]
450macro_rules! use_lower_case {
451 ($input:ident) => {
452 $input = $input.to_lowercase();
453 };
454}
455
456///```
457/// /// macro can create a file and add text at him
458/// /// example
459///fn main() -> std::io::Result<()> {
460///use_createFile!("ak2","/home/ak/Desktop","Hello from ak-macros");
461///Ok(())
462/// }
463/// /// the macro take three value
464/// /// 1 - File name
465/// /// 2 - File Path
466/// /// 3 - Text
467///
468/// ```
469#[macro_export]
470macro_rules! use_createFile {
471 ($file_name:expr, $file_path:expr,$input_text:expr) => {
472 use std::fs::File;
473 use std::io::prelude::*;
474 use std::path::{Path, PathBuf}; // Import PathBuf for constructing paths
475
476 let file_path = PathBuf::from($file_path).join($file_name); // Construct the file path
477 let mut file = File::create(&file_path)?; // Use ? to propagate errors
478 file.write_all($input_text.as_bytes())?; // Use ? to propagate errors
479 };
480}
481
482///```
483/// /// This macro places a string in the memory,
484/// /// and if you define a new variable that carries the value of that string,
485/// /// it will not take up a new space in the memory.
486/// ///example
487/// let my_name = set_String!("ak Macros crate");
488/// akp!("{}",my_name);
489///```
490#[macro_export]
491macro_rules! set_String {
492 ($the_text:expr) => {
493 String::from($the_text)
494 };
495}
496
497///```
498/// /// Positive_number macro can set Positive Numbers Only
499/// /// example
500/// let num = Positive_number!(20);
501/// akp!("Age is :{}", num); //OutPut: Age is :20
502
503/// /// Wrong Syntax
504///let num = Positive_number!(-20);
505///akp!("{}", num); /// Number Must be Positive
506/// ```
507#[macro_export]
508macro_rules! Positive_number {
509 ($num:expr) => {{
510 let num = $num;
511 if num < 0 {
512 panic!("Number must be positive!");
513 }
514 num as usize
515 }};
516}
517
518///```
519/// /// Positive_number macro can set Positive Numbers Only
520/// /// example
521/// let num = Negative_number!(-20);
522/// akp!("Age is :{}", num); //OutPut: Age is :-20
523
524/// /// Wrong Syntax
525///let num = Negative_number!(20);
526///akp!("{}", num); /// Number Must be Negative
527/// ```
528#[macro_export]
529macro_rules! Negative_number {
530 ($num:expr) => {{
531 let num = $num;
532 if num > 0 {
533 panic!("Number must be Negative!");
534 }
535 num as isize
536 }};
537}
538
539///```
540/// ///Ram_size Macro can get the All Ram Size
541/// /// example
542/// let my_ram = Ram_size!();
543/// akp!("Total RAM: {:.2} GB", my_ram); /// Total RAM: 7.67 GB
544/// akp!("Total RAM: {} GB", my_ram); // Total RAM: 7.670555114746094 GB
545/// ```
546#[macro_export]
547macro_rules! Ram_size {
548 () => {{
549 let mut ram_gb = 0.0;
550 if let Ok(meminfo) = std::fs::read_to_string("/proc/meminfo") {
551 for line in meminfo.lines() {
552 if line.starts_with("MemTotal:") {
553 let ram_kb: u64 = line.split_whitespace().nth(1).unwrap().parse().unwrap();
554 ram_gb = ram_kb as f64 / 1024.0 / 1024.0;
555 break;
556 }
557 }
558 } else {
559 eprintln!("Failed to read /proc/meminfo");
560 }
561 ram_gb
562 }};
563}
564///```
565/// /// Get_CPU macro can get the cpu informaion
566/// /// example
567/// let my_cpu = Get_CPU!();
568/// akp!("My CPU is: {}",my_cpu);
569/// ```
570#[macro_export]
571macro_rules! Get_CPU {
572 () => {{
573 let mut cpu_name = String::new();
574 if let Ok(cpuinfo) = std::fs::read_to_string("/proc/cpuinfo") {
575 for line in cpuinfo.lines() {
576 if line.starts_with("model name") {
577 let parts: Vec<&str> = line.split(":").collect();
578 if parts.len() >= 2 {
579 cpu_name = parts[1].trim().to_string();
580 break; // Once we've found the CPU name, we can break out of the loop
581 }
582 }
583 }
584 } else {
585 println!("Failed to read CPU info.");
586 }
587 cpu_name
588 }};
589}
590
591/// ```
592/// ///macro can looping at any array content
593/// /// macro take three values
594/// /// 1- the array
595/// /// 2- variableName
596/// /// 3- method
597/// /// Example
598/// let tarr: [&str; 3] = ["Max", "Jack", "Aly"];
599/// use_loopAt!(tarr, varr, {
600/// println!("hello {}", varr);
601/// });
602///});
603/// /// you should't type Variable like that
604/// use_loopAt!(tarr,{
605/// println!("hello world");
606/// });
607///```
608#[macro_export]
609macro_rules! use_loopAt {
610 ($arr:expr, $var:ident, $method:tt) => {
611 for $var in $arr {
612 $method
613 }
614 };
615 ($arr:expr, $method:tt) => {
616 for ii in $arr {
617 $method
618 }
619 };
620}
621
622/// ## `use_time`
623///
624/// The `use_time` macro pauses the execution of the code for a specified number of seconds, similar to how `setTimeout` works in JavaScript.
625///
626/// # Examples
627///
628/// ```rust
629/// fn main() {
630/// println!("hello world");
631/// use_time!(5); // Pauses execution for 5 seconds
632/// println!("hello dev...!");
633/// }
634/// ```
635#[macro_export]
636macro_rules! use_time {
637 ($expr:expr) => {
638 use std::thread;
639 use std::time::Duration;
640 thread::spawn(|| {
641 thread::sleep(Duration::from_secs($expr));
642 })
643 .join()
644 .unwrap();
645 };
646}