is_not

This crate exports two very simple attribute macros. is returns the token stream as is and not returns an empty token stream.

These are very similar to the #[cfg(...)] attributes, but they can be exported from a crate for things that need to be enabled if a dependency has certain features enabled. It additionally has the advantage that it also type checks. If you mis-spell something inside of #[cfg(mis-spelled)] it will always be disabled, where these attributes must exist in the namespace.

For example, let's say you want to allow different algorithms or implementations inside of a library that can be turned on and off and add expensive compile times due to dependencies or will be in the hot path of an application's main loop.

```rust // algo crate // This crate ensures that at least one of foo and bar is active using a build script or more fancy cfg attributes.

[cfg(feature = "foo")]

pub use isnot::{is as isfoo, not as not_foo};

[cfg(not(feature = "foo"))]

pub use isnot::{not as isfoo, is as not_foo};

[cfg(feature = "bar")]

pub use isnot::{is as isbar, not as not_bar};

[cfg(not(feature = "bar"))]

pub use isnot::{not as isbar, is as not_bar};

[cfg(feature = "foo")]

mod foo { fn foo(a: Foo) -> i32 { // algorithm } struct Foo { // fields } }

[cfg(feature = "foo")]

mod bar { fn bar(a: Bar) -> i32 { // algorithm } struct Bar { // fields } } ```

```rust // app crate // both of these functions will exist, though compile time flags given to the algo crate will change how they are compiled in the app crate.

// You can ensure that at least one is turned on

[not_foo]

[not_bar]

compile_error!("Either foo or bar or both should be enabled in algo crate");

[is_foo]

fn call_foo() -> i32 { algo::foo::foo(algo::foo::Foo{}) }

[not_foo]

fn callfoo() -> i32 { callbar() }

[is_bar]

fn call_bar() -> i32 { algo::bar::bar(algo::bar::Bar{}) }

[not_bar]

fn callbar() -> i32 { callfoo() }

fn callalgo() -> i32 { if crate::usefoo() { callfoo() } else { callbar() } } ```