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}