1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! # Case Clause Macro
//! The purpose of the macro implemented here is to create an alternative to huge if else cascades.
//! ## Current State: The Idea is based on haskell [case clauses](https://www.haskell.org/tutorial/patterns.html):
//!
//! ```haskell
//! sign x | x > 0 = 1
//! | x == 0 = 0
//! | x < 0 = -1
//! ```
//! This would normally look like this in [Rust](https://www.rust-lang.org/):
//! ```rust
//! # let x = 5; // Added variable declaration
//! let result = if x > 0 {
//! 1
//! } else if x == 0 {
//! 0
//! } else if x < 0 {
//! -1
//! } else {
//! 0
//! };
//! ```
//! If you now want to display this using a match case, which is normally the environment in rust for pattern matching, it would look different:
//! ```rust
//! # let x = 5; //Added variable declaration
//! match x {
//! x if x > 0 => 1,
//! x if x == 0 => 0,
//! x if x < 0 => -1,
//! _ => 0,
//! };
//! ```
//! I found both solutions extremely clunky and therefore tiring to work with. That's why the macro from this crate works like this:
//! ```rust
//! use case_clause::case;
//! # let x = 5; // Added variable declaration
//! let result = case!(
//! x > 0 => 1,
//! x == 0 => 0,
//! x < 0 => -1,
//! true => 0,
//! );
//! ```
//! To be fair, this is a first step towards creating a more elegant alternative to rust's `match` environment, which still works elegantly when processing boolean values.
/// # A macro that provides Haskell-style case expressions for Rust.
///
/// This macro allows you to write guard-based pattern matching similar to Haskell's case expressions.
/// Each guard is evaluated in order, and the first one that evaluates to `true` will have its
/// corresponding result expression returned.
///
/// ## Examples
///
/// ```rust
/// use case_clause::case;
///
/// let x = 5;
/// let result = case!(
/// x > 10 => "large",
/// x > 0 => "positive",
/// x == 0 => "zero",
/// true => "negative"
/// );
/// assert_eq!(result, "positive");
/// ```
///
/// ## Panics
///
/// This macro will panic with "unreachable" if none of the guards match. Make sure to include
/// a catch-all case (like `true => default_value`) to avoid this.
/// # An alternative case macro that uses if-else chains instead of match expressions.
///
/// This macro provides similar functionality to `case!` but uses a chain of if-else
/// statements internally. Each condition is evaluated in order until one matches.
///
/// ## Examples
///
/// ```rust
/// use case_clause::case_pattern;
///
/// let x = -3;
/// let result = case_pattern!(
/// x > 0 => 1,
/// x == 0 => 0,
/// x < 0 => -1,
/// );
/// assert_eq!(result, -1);
/// ```
///
/// ## Panics
///
/// This macro will panic with "unreachable" if none of the conditions match. Make sure
/// to include a condition that will always be true as the last case.