1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//! rust-expect-macros: Procedural macros for rust-expect
//!
//! This crate provides compile-time macros for the rust-expect terminal automation library:
//!
//! - [`patterns!`] - Define pattern sets for expect operations
//! - [`regex!`] - Compile-time validated regex patterns
//! - [`dialog!`] - Define interactive dialog scripts
//! - [`timeout!`] - Parse timeout duration specifications
//!
//! # Example: Pattern Matching
//!
//! ```ignore
//! use rust_expect_macros::patterns;
//!
//! let patterns = patterns! {
//! "login:",
//! "password:",
//! regex(r"\$\s*$"),
//! };
//! ```
//!
//! # Example: Dialog Script
//!
//! ```ignore
//! use rust_expect_macros::dialog;
//!
//! let script = dialog! {
//! expect "login:";
//! sendln "admin";
//! expect "password:";
//! sendln "secret";
//! expect_re r"\$\s*$"
//! };
//! ```
//!
//! # Example: Validated Regex
//!
//! ```ignore
//! use rust_expect_macros::regex;
//!
//! // Compile-time validated regex
//! let prompt = regex!(r"^\w+@\w+:\S+\$\s*$");
//! ```
//!
//! # Example: Human-Readable Timeout
//!
//! ```ignore
//! use rust_expect_macros::timeout;
//!
//! let duration = timeout!(5 s);
//! let long_timeout = timeout!(2 m + 30 s);
//! ```
// In proc-macro crates, passing parsed input by value is idiomatic
use TokenStream;
use parse_macro_input;
/// Define a set of patterns for use with expect operations.
///
/// This macro creates a `PatternSet` with compile-time validated patterns.
///
/// # Syntax
///
/// ```ignore
/// patterns! {
/// "literal pattern",
/// name: "named pattern",
/// regex(r"regex\s+pattern"),
/// glob("glob*pattern"),
/// "pattern" => action_expression,
/// }
/// ```
///
/// # Examples
///
/// ```ignore
/// let login_patterns = patterns! {
/// login: "login:",
/// password: "password:",
/// prompt: regex(r"\$\s*$"),
/// };
///
/// // Use with session.expect()
/// let matched = session.expect(&login_patterns).await?;
/// ```
/// Compile-time validated regex pattern.
///
/// Creates a lazily-initialized `regex::Regex` that is validated at compile time.
/// Invalid regex patterns will cause a compilation error.
///
/// # Examples
///
/// ```ignore
/// use rust_expect_macros::regex;
///
/// // Valid regex - compiles successfully
/// let prompt = regex!(r"^\w+@\w+:\S+\$\s*$");
///
/// // Invalid regex - compilation error
/// // let bad = regex!(r"[invalid");
/// ```
/// Define an interactive dialog script.
///
/// Creates a `Dialog` that can be executed against a session, automating
/// send/expect sequences.
///
/// # Commands
///
/// - `send "text"` - Send text without newline
/// - `sendln "text"` - Send text with newline
/// - `expect "pattern"` - Wait for literal pattern
/// - `expect_re "regex"` - Wait for regex pattern (validated at compile time)
/// - `wait duration` - Wait for a duration
/// - `timeout duration` - Set timeout for subsequent operations
///
/// # Examples
///
/// ```ignore
/// use rust_expect_macros::dialog;
/// use std::time::Duration;
///
/// let login_script = dialog! {
/// timeout Duration::from_secs(30);
/// expect "login:";
/// sendln "admin";
/// expect "password:";
/// sendln "secret123";
/// expect_re r"\$\s*$"
/// };
///
/// // Execute the dialog
/// session.run_dialog(&login_script).await?;
/// ```
/// Parse a human-readable timeout specification.
///
/// Creates a `std::time::Duration` from a human-readable format.
///
/// # Supported Units
///
/// - `ns`, `nanos`, `nanoseconds` - Nanoseconds
/// - `us`, `micros`, `microseconds` - Microseconds
/// - `ms`, `millis`, `milliseconds` - Milliseconds
/// - `s`, `sec`, `secs`, `seconds` - Seconds
/// - `m`, `min`, `mins`, `minutes` - Minutes
/// - `h`, `hr`, `hrs`, `hours` - Hours
///
/// # Examples
///
/// ```ignore
/// use rust_expect_macros::timeout;
///
/// let short = timeout!(100 ms);
/// let medium = timeout!(5 s);
/// let long = timeout!(2 m);
/// let compound = timeout!(1 m + 30 s + 500 ms);
/// ```