# make-noop
[](https://crates.io/crates/make-noop)
[](https://docs.rs/make-noop)
[](https://github.com/s23b/make-noop/actions/workflows/ci.yml)
[](#license)
Attribute macros that replace function, method, and `impl`-block bodies with
no-ops, and strip a struct down to a unit struct.
The point is to toggle that no-op'ing on a compile-time condition. Pair any of
these macros with [`cfg_attr`] so that a feature flag (or any `cfg`) decides
whether the real implementation is compiled or quietly replaced with a stub —
no `#[cfg]` blocks duplicating each item, and no runtime branch.
```rust
use make_noop::{make_noop, make_unit, noop_returns};
// With the `dry-run` feature on, this becomes a no-op; otherwise it runs for real.
#[cfg_attr(feature = "dry-run", make_noop)]
fn launch_missiles(hardware: &Hardware) {
hardware.arm();
hardware.fire();
}
// In `dry-run`, report success without touching the network.
#[cfg_attr(feature = "dry-run", noop_returns(Ok(())))]
fn upload(client: &Client, blob: &[u8]) -> Result<(), Error> {
client.put(blob)
}
// In `dry-run`, collapse the telemetry buffer to a zero-sized unit struct.
#[cfg_attr(feature = "dry-run", make_unit)]
struct Telemetry {
events: Vec<Event>,
}
```
[`cfg_attr`]: https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute
## Highlights
- `#[make_noop]` applies to a free function, a single method, or an entire
`impl` block (every method becomes a no-op).
- Value-returning functions return `Default::default()` by default; override the
returned value with `#[noop_returns(EXPR)]`.
- `#[noop_returns(EXPR)]` works standalone on a function/method, **or** on a
whole `impl` block — where it sets a shared return value for every method,
except those carrying their own `#[noop_returns(OTHER)]`.
- `#[make_unit]` strips a struct's fields, leaving a unit struct.
- Functions with no return value get an empty body and never return a value.
- The original body is discarded — it is not type-checked or executed. Imports
or items referenced *only* from a no-op'd body may therefore become unused.
## Installation
```sh
cargo add make-noop
```
## Usage
### Free functions
```rust
use make_noop::{make_noop, noop_returns};
#[make_noop]
fn does_nothing() {
panic!("skipped");
}
#[make_noop]
fn returns_default() -> Vec<u8> {
unreachable!() // returns Vec::new()
}
#[noop_returns(String::from("hi"))]
fn greeting() -> String {
unreachable!() // returns "hi"
}
```
### Impl blocks
`#[make_noop]` on an `impl` block makes every method a no-op. Individual methods
can opt into a custom return value with `#[noop_returns(EXPR)]`:
```rust
use make_noop::{make_noop, noop_returns};
struct Service;
#[make_noop]
impl Service {
fn code(&self) -> i32 {
unreachable!() // returns 0 (Default)
}
#[noop_returns(String::from("hi"))]
fn greeting(&self) -> String {
unreachable!() // returns "hi"
}
}
```
`#[noop_returns(EXPR)]` can also be applied to the `impl` block itself to set a
shared default for all methods, still overridable per method:
```rust
use make_noop::noop_returns;
struct Codes;
#[noop_returns(3)]
impl Codes {
fn first(&self) -> i32 {
unreachable!() // returns 3
}
#[noop_returns(42)]
fn second(&self) -> i32 {
unreachable!() // returns 42
}
}
```
### Unit structs
`#[make_unit]` discards a struct's fields, leaving a unit struct. It works on
structs with named fields and on tuple structs; attributes, visibility, and
generics are preserved:
```rust
use make_noop::make_unit;
#[make_unit]
#[derive(Debug, Default)]
pub struct Config {
verbose: bool,
retries: u32,
}
// Expands to `pub struct Config;` (still `#[derive(Debug, Default)]`)
```
## Notes
- A function that returns a value must have a return type implementing
[`Default`] unless you supply `#[noop_returns(EXPR)]`.
- The original body is discarded outright: it is neither type-checked nor
executed. Anything referenced *only* from inside a no-op'd body (for example an
import) may consequently be reported as unused.
## Minimum supported Rust version
`make-noop` requires **Rust 1.87** or newer. The MSRV is verified in CI and may
be raised in a minor version bump.
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
<http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or
<http://opensource.org/licenses/MIT>)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.