Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vrmiguel/negate
Attribute macro that generates negated versions of`is_something` functions
https://github.com/vrmiguel/negate
macro proc-macro proc-macro-attributes rust rust-lang
Last synced: 4 months ago
JSON representation
Attribute macro that generates negated versions of`is_something` functions
- Host: GitHub
- URL: https://github.com/vrmiguel/negate
- Owner: vrmiguel
- License: mit
- Created: 2021-09-03T21:28:18.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2021-09-04T23:26:01.000Z (over 3 years ago)
- Last Synced: 2024-09-17T01:18:33.051Z (5 months ago)
- Topics: macro, proc-macro, proc-macro-attributes, rust, rust-lang
- Language: Rust
- Homepage: https://crates.io/crates/negate
- Size: 29.3 KB
- Stars: 9
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# negate
negate is a simple attribute macro that negates a given function.
## Usage
### `#[negate]`
Given a function of the form `is_*` that returns a boolean value, the macro will create a `is_not_*` function that negates the given function.
```rust
struct Word(&'static str);impl Word {
pub fn new(word: &'static str) -> Self {
Self (word)
}#[negate] // <- negate will implement a `is_not_uppercase` function!
pub fn is_uppercase(&self) -> bool {
self.0 == self.0.to_uppercase()
}
}
let my_name = Word::new("My Name");assert!(my_name.is_not_uppercase());
```
### `#[negate(name = "...")]`
Using the name attribute allows you to set the name of the generated function. This also allows the usage of the [negate] macro with functions that do not start with `is_`.
```rust
use negate::negate;pub enum TaskState {
Ready,
Finished,
}pub struct Reactor {
tasks: HashMap,
}impl Reactor {
// Generates the `is_finished` function
#[negate(name = "is_finished")]
pub fn is_ready(&self, id: usize) -> bool {
self.tasks.get(&id).map(|state| match state {
TaskState::Ready => true,
_ => false,
}).unwrap_or(false)
}
}
```### `#[negate(docs = "...")]`
Using the docs attribute allows you to customize the doc-string of the generated function.
```rust
use negate::negate;
#[negate(name = "is_odd", docs = "returns true if the given number is odd")]
fn is_even(x: i32) -> bool {
x % 2 == 0
}
assert!(is_odd(5));
```## How does the generated code look like?
### Non-associated functions
```rust
#[negate]
pub fn is_even(x: i32) -> bool {
x % 2 == 0
}
```Will expand to:
```rust
pub fn is_even(x: i32) -> bool {
x % 2 == 0
}/// This is an automatically generated function that denies [`is_even`].
/// Consult the original function for more information.
pub fn is_not_even(x: i32) -> bool {
!is_even(x)
}
```Using generics is likewise not a problem
```rust
#[negate]
fn is_equal(x: T, y: T) -> bool
where
T: Eq,
{
x == y
}
```The generated negated function:
```rust
/// This is an automatically generated function that denies [`is_equal`].
/// Consult the original function for more information.
fn is_not_equal(x: T, y: T) -> bool
where
T: Eq,
{
!is_equal(x, y)
}
```### Associated functions
```rust
struct BigInt {
..
};impl BigInt {
#[negate(name = "is_negative", docs = "Returns true if the number is negative and false if the number is zero or positive.")]
pub fn is_positive(&self) -> bool { .. }
}
```Becomes:
```rust
impl BigInt {
pub fn is_positive(&self) -> bool { .. }
/// Returns true if the number is negative and false if the number is zero or positive.
pub fn is_negative(&self) -> bool {
!self.is_positive()
}
}
```