Skip to content

Commit

Permalink
Adjust style guide (loops) and add unreachable macro (#1252)
Browse files Browse the repository at this point in the history
* Adjust style guide (loops) and add unreachable macro

* Add macros module to lib.rs

* Update docs/STYLE_GUIDE.md

Co-authored-by: Malte Kliemann <[email protected]>

* Move macro to zeitgeist-macros and add examples

---------

Co-authored-by: Malte Kliemann <[email protected]>
  • Loading branch information
sea212 and maltekliemann authored Feb 9, 2024
1 parent 235f341 commit 20358a9
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 4 deletions.
22 changes: 18 additions & 4 deletions docs/STYLE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ duplicating documentation.

- Exceed 70 lines of code per function only in exceptional circumstances. Aim
for less.
- No `while` in production. All `for` loops must have a maximum number of
passes.
- Prefer `for` loops over `while` loops. All loops (of any kind) must have a
maximum number of passes.
- Use depth checks when using recursion in production. Use recursion only if the
algorithm is defined using recursion.
- Avoid `mut` in production code if possible without much pain.
- Mark all extrinsics `transactional`, even if they satisfy
the verify-first/write-later principle.
- Mark all extrinsics `transactional`, even if they satisfy the
verify-first/write-later principle.
- Avoid indentation over five levels; never go over seven levels.
- All public functions must be documented. Documentation of `pub(crate)` and
private functions is optional but encouraged.
Expand Down Expand Up @@ -156,3 +156,17 @@ duplicating documentation.
- For larger modules, use one test file per extrinsic for unit tests. Make unit
tests as decoupled as possible from other modules. Place end-to-end and
integration tests in extra files.
- If possible, test unreachable code and states thought to be impossible using
the following schema:

```rust
// In code logic
zeitgeist_macros::unreachable_non_terminating!(condition, log_target, message)
```

```rust
// In test
#[test]
#[should_panic(expected = message)]
// Cause assertion
```
58 changes: 58 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,61 @@ macro_rules! create_b_tree_map {
[$(($key, $value),)*].iter().cloned().collect::<alloc::collections::BTreeMap<_, _>>()
}
}

/// This macro does ensure that a condition `$condition` is met, and if it is not met
/// it will log a message `$message` with optional message arguments `message_args` to
/// an optional log target `$log_target`, cause an assertion in a test environment
/// and execute some optional extra code.
///
/// ```ignore
/// // Examples:
/// unreachable_non_terminating!(a == b, "a does not equal b");
/// unreachable_non_terminating!(a == b, log_target, "a does not equal b");
/// unreachable_non_terminating!(a == b, "{:?} != {:?}", a, b);
/// unreachable_non_terminating!(a == b, log_target, "{:?} != {:?}", a, b);
/// ```
#[macro_export]
macro_rules! unreachable_non_terminating {
($condition: expr, $message: literal, $($message_args: tt)*) => {
let message = format!($message, $($message_args)*);

#[cfg(test)]
assert!($condition, "{}", message);

if !$condition {
log::warn!("{}", message);
}
};
($condition: expr, $log_target: ident, $message: literal, $($message_args: tt)*) => {
let message = format!($message, $($message_args)*);

#[cfg(test)]
assert!($condition, "{}", message);

if !$condition {
log::warn!(target: $log_target, "{}", message);
}
};
($condition: expr, $extra_code: expr, $message: literal, $($message_args: tt)*) => {
let message = format!($message, $($message_args)*);

#[cfg(test)]
assert!($condition, "{}", message);

if !$condition {
log::warn!("{}", message);
$extra_code;
}
};
($condition: expr, $log_target: ident, $extra_code: expr, $message: literal, $($message_args: tt)*) => {
let message = format!($message, $($message_args)*);

#[cfg(test)]
assert!($condition, "{}", message);

if !$condition {
log::warn!(target: $log_target, "{}", message);
$extra_code;
}
};
}

0 comments on commit 20358a9

Please sign in to comment.