clap_version_flag/macros.rs
1// Project: clap-version-flag
2// File: src/macros.rs
3// Author: Hadi Cahyadi <cumulus13@gmail.com>
4// Date: 2025-12-12
5// Description: Main and helper macros for clap-version-flag
6// License: MIT
7
8//! Macros for creating and working with `ColorfulVersion`
9//!
10//! This module contains the main `colorful_version!` macro and
11//! additional helper macros for ease of use.
12
13/// Main macro for easy creation of ColorfulVersion from Cargo.toml
14///
15/// **IMPORTANT**: This macro uses `env!()` which expands at the caller's location,
16/// so it will correctly pick up the caller's package information, not this library's.
17///
18/// # Examples
19/// ```
20/// use clap_version_flag::colorful_version;
21///
22/// // With default colors - gets info from YOUR Cargo.toml
23/// let version = colorful_version!();
24/// println!("{}", version); // Prints: your-app-name v1.0.0 by Your Name
25///
26/// // With custom hex colors
27/// let version = colorful_version!("#FFFFFF", "#AA00FF", "#FFFF00", "#00FFFF");
28/// ```
29#[macro_export]
30macro_rules! colorful_version {
31 () => {
32 // env!() expands at the CALLER's location, not here!
33 // This means it will read from the caller's Cargo.toml
34 $crate::ColorfulVersion::new(
35 env!("CARGO_PKG_NAME"),
36 env!("CARGO_PKG_VERSION"),
37 env!("CARGO_PKG_AUTHORS"),
38 )
39 };
40
41 ($name_fg:expr, $name_bg:expr, $version:expr, $author:expr) => {
42 $crate::ColorfulVersion::new(
43 env!("CARGO_PKG_NAME"),
44 env!("CARGO_PKG_VERSION"),
45 env!("CARGO_PKG_AUTHORS"),
46 )
47 .with_hex_colors($name_fg, $name_bg, $version, $author)
48 .unwrap_or_else(|e| panic!("clap-version-flag: Invalid hex color format: {}", e))
49 };
50}
51
52/// Macro to create a colorful version with complete configuration
53///
54/// # Examples
55///
56/// ## Create with custom values
57/// ```
58/// use clap_version_flag::colorful_version_full;
59///
60/// let version = colorful_version_full!("myapp", "1.0.0", "John Doe");
61/// assert_eq!(version.package_name(), "myapp");
62/// ```
63///
64/// ## Create with custom values and colors
65/// ```
66/// use clap_version_flag::colorful_version_full;
67///
68/// let version = colorful_version_full!(
69/// "myapp", "1.0.0", "John Doe",
70/// "#FFFFFF", "#AA00FF", "#FFFF00", "#00FFFF"
71/// );
72/// ```
73#[macro_export]
74macro_rules! colorful_version_full {
75 ($name:expr, $version:expr, $author:expr) => {
76 $crate::ColorfulVersion::new($name, $version, $author)
77 };
78
79 ($name:expr, $version:expr, $author:expr,
80 $name_fg:expr, $name_bg:expr, $version_color:expr, $author_color:expr) => {
81 $crate::ColorfulVersion::new($name, $version, $author)
82 .with_hex_colors($name_fg, $name_bg, $version_color, $author_color)
83 .expect("Invalid hex color format")
84 };
85}
86
87/// Macro to create a colorful version with RGB colors
88///
89/// # Examples
90/// ```
91/// use clap_version_flag::colorful_version_rgb;
92///
93/// let version = colorful_version_rgb!(
94/// (255, 255, 255), // name foreground
95/// (170, 0, 255), // name background
96/// (255, 255, 0), // version color
97/// (0, 255, 255) // author color
98/// );
99/// ```
100#[macro_export]
101macro_rules! colorful_version_rgb {
102 ($name_fg:expr, $name_bg:expr, $version:expr, $author:expr) => {
103 $crate::ColorfulVersion::new(
104 env!("CARGO_PKG_NAME"),
105 env!("CARGO_PKG_VERSION"),
106 env!("CARGO_PKG_AUTHORS"),
107 )
108 .with_rgb_colors($name_fg, $name_bg, $version, $author)
109 };
110}
111
112/*
113NOTE: derive_colorful_version macro is commented out for now.
114It requires more complex implementation with trait bounds.
115Will be added in future version if there's demand.
116
117/// Macro for derive helper to add colorful version to your CLI struct
118///
119/// This is useful if you want to add version functionality directly to your CLI struct.
120///
121/// # Examples
122/// ```ignore
123/// use clap::Parser;
124/// use clap_version_flag::derive_colorful_version;
125///
126/// #[derive(Parser)]
127/// struct Cli {
128/// name: String,
129/// }
130///
131/// derive_colorful_version!(Cli);
132///
133/// fn main() {
134/// let version = Cli::colorful_version();
135/// version.print();
136/// }
137/// ```
138#[macro_export]
139macro_rules! derive_colorful_version {
140 ($struct_name:ident) => {
141 impl $struct_name {
142 /// Get colorful version for this CLI application
143 ///
144 /// This method returns a `ColorfulVersion` instance using the
145 /// information from your `Cargo.toml` file.
146 pub fn colorful_version() -> $crate::ColorfulVersion {
147 $crate::colorful_version!()
148 }
149
150 /// Parse command with automatic colorful version handling
151 ///
152 /// This method combines parsing and version handling in one call.
153 /// If the user passes `--version` or `-V`, it will print the
154 /// colorful version and exit.
155 ///
156 /// # Errors
157 ///
158 /// Returns an error if clap fails to parse the arguments.
159 pub fn parse_with_colorful_version() -> Result<Self, clap::Error>
160 where
161 Self: clap::FromArgMatches + clap::CommandFactory,
162 {
163 let version = Self::colorful_version();
164 $crate::parse_with_version(Self::command(), &version)
165 }
166 }
167 };
168}
169*/
170
171#[cfg(test)]
172mod tests {
173 // use crate::ColorfulVersion;
174
175 #[test]
176 fn test_colorful_version_full_without_colors() {
177 let version = colorful_version_full!("testapp", "1.0.0", "Test Author");
178 assert_eq!(version.package_name(), "testapp");
179 assert_eq!(version.version(), "1.0.0");
180 assert_eq!(version.author(), "Test Author");
181 }
182
183 #[test]
184 fn test_colorful_version_full_with_colors() {
185 let version = colorful_version_full!(
186 "testapp",
187 "1.0.0",
188 "Test Author",
189 "#FFFFFF",
190 "#AA00FF",
191 "#FFFF00",
192 "#00FFFF"
193 );
194 assert_eq!(version.package_name(), "testapp");
195 }
196
197 #[test]
198 fn test_colorful_version_rgb() {
199 let version = colorful_version_rgb!((255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0));
200 // This will use env! so it gets the crate's own name in tests
201 assert_eq!(version.package_name(), env!("CARGO_PKG_NAME"));
202 }
203}