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}