stub_macro/lib.rs
1//! `stub!()` can be assigned to a variable:
2//!
3//! ```rust
4//! # #[macro_use] extern crate stub_macro;
5//! # fn main() {
6//! # fn assign() {
7//! let username = stub!(String);
8//! # }
9//! # }
10//! ```
11//!
12//! This allows you to specify just type of the variable and continue working on other code, then come back later and specify its value.
13//!
14//! ## Examples
15//!
16//! ```
17//! # #[macro_use] extern crate stub_macro;
18//! # fn main() {
19//! fn assign() {
20//! // you can assign stub!() to a variable
21//! let username = stub!(String);
22//! println!("Hello {username}")
23//! }
24//!
25//! fn return_position() -> String {
26//! // you can use stub!() like todo!() in return position
27//! stub!()
28//! }
29//!
30//! fn infer_type() {
31//! // you can let the compiler automatically infer the type
32//! let status = stub!();
33//! if status { println!("Success") }
34//! }
35//!
36//! fn explicit_type() {
37//! // you can specify the type explicitly
38//! let status: bool = stub!();
39//! if status { println!("Success") }
40//! }
41//!
42//! fn custom_message() {
43//! // you can add a custom message
44//! let status: bool = stub!("Send a request to GitHub");
45//! if status { println!("Success") }
46//! }
47//!
48//! fn impl_example() -> impl Iterator<Item=u32> {
49//! // you can use stub!() in return position even with `impl Trait` return type
50//! // note: `impl Trait` must be written as `impl dyn Trait` due to `macro_rules!` limitation
51//! stub!(impl dyn Iterator<Item=u32>)
52//! }
53//!
54//! fn explicit_type_with_message_example() -> u32 {
55//! // you can add
56//! stub!(u32, "Assigned to: {}", "John")
57//! }
58//!
59//! fn explicit_type_example() -> u32 {
60//! stub!(u32)
61//! }
62//!
63//! fn implicit_type_with_message_example() -> u32 {
64//! stub!("Assigned to: {}", "John")
65//! }
66//!
67//! fn implicit_type_example() -> u32 {
68//! stub!()
69//! }
70//! # }
71//! ```
72//!
73//! ## Behavior
74//!
75//! When a stub is invoked, it will panic like a `todo!()` macro.
76//! However, unlike a `todo!()` macro, it will not make the subsequent parts of your code unreachable.
77//!
78//! If a custom message is provided, it will be included in the panic message.
79//!
80//! ## Notes
81//!
82//! - The `stub!()` macro is intended for use during development and should be
83//! replaced with actual implementations before production use.
84//! - When using `impl Trait` in return position, you must use `impl dyn Trait` in the macro invocation due to a limitation in `macro_rules!`
85//!
86
87#![no_std]
88
89/// See the crate-level documentation for the overview of this macro
90#[macro_export]
91macro_rules! stub {
92 (impl $ty:ty) => {{
93 $crate::_stub::<Box<$ty>>()
94 }};
95 ($ty:ty, $msg:literal$(, $args:tt)*) => {{
96 $crate::_stub_msg::<$ty>(&format!($msg$(, $args)*))
97 }};
98 ($ty:ty) => {{
99 $crate::_stub::<$ty>()
100 }};
101 ($msg:literal$(, $args:tt)*) => {{
102 $crate::_stub_msg(&format!($msg$(, $args)*))
103 }};
104 () => {{
105 $crate::_stub()
106 }};
107}
108
109#[doc(hidden)]
110pub fn _stub<T>() -> T {
111 todo!()
112}
113
114#[doc(hidden)]
115pub fn _stub_msg<T>(msg: &str) -> T {
116 todo!("{msg}")
117}
118
119#[cfg(test)]
120mod tests {
121 #[test]
122 #[should_panic]
123 fn test_panic() {
124 stub!()
125 }
126}