make-noop 0.1.0

Attribute macros that replace function, method, and impl-block bodies with no-ops, with customizable return values.
Documentation
  • Coverage
  • 100%
    4 out of 4 items documented0 out of 3 items with examples
  • Size
  • Source code size: 33.68 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 304.54 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 7s Average build duration of successful builds.
  • all releases: 7s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • s23b/make-noop
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • s23b

make-noop

Crates.io Docs.rs CI License: MIT OR Apache-2.0

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.

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>,
}

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

cargo add make-noop

Usage

Free functions

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)]:

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:

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:

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

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.