[−][src]Crate operator_sugar
This crate provides simple macros that serve as syntactic sugar to make overloading operators in Rust easier.
The basic syntax for binary operators is in this format:
struct Left(i32); struct Right(i32); struct Answer(i32); operator!(Left, Right: a + b -> Answer { // Implementation of the operator function here Answer(a.0 + b.0) });
Meta Attributes
Attributes can be applied to the impl
block (which implements e.g. Add
) and the fn
block respectively:
struct Left(i32); struct Right(i32); struct Answer(i32); operator!( #[doc("This attribute will be applied on the `impl` block")] Left, Right: #[doc("This attribute will be applied on the `fn` block")] a + b -> Answer { Answer(a.0 + b.0) });
Generics
Generics can be used on the three types and on the impl
block.
Due to disambiguation, generic parameters for the impl
block must be written in {}
rather
than <>
.
use core::ops::Add; struct Left<T>(T) where T: Add<i32, Output = i32>; struct Right(i32); struct Answer(i32); operator!( {T: Add<i32, Output = i32>} Left<T>, Right: a + b -> Answer { Answer(a.0 + b.0) });
List of operators
For conciseness, these definitions are defined for each of the following examples:
use operator_sugar::*; #[derive(Debug)] struct Left(i32); #[derive(Debug)] struct Right(i32); #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
Addition
operator!(Left, Right: a + b -> Answer { Answer(a.0 + b.0) }); fn main() { assert_eq!(Left(1) + Right(2), Answer(3)); }
Subtraction
operator!(Left, Right: a - b -> Answer { Answer(a.0 - b.0) }); fn main() { assert_eq!(Left(1) - Right(2), Answer(-1)); }
Multiplication
operator!(Left, Right: a * b -> Answer { Answer(a.0 * b.0) }); fn main() { assert_eq!(Left(3) * Right(2), Answer(6)); }
Division
operator!(Left, Right: a / b -> Answer { Answer(a.0 / b.0) }); fn main() { assert_eq!(Left(8) / Right(2), Answer(4)); }
Remainder
operator!(Left, Right: a % b -> Answer { Answer(a.0 % b.0) }); fn main() { assert_eq!(Left(9) % Right(5), Answer(4)); }
Bitwise AND
operator!(Left, Right: a & b -> Answer { Answer(a.0 & b.0) }); fn main() { assert_eq!(Left(5) & Right(6), Answer(4)); }
Bitwise OR
operator!(Left, Right: a | b -> Answer { Answer(a.0 | b.0) }); fn main() { assert_eq!(Left(5) | Right(6), Answer(7)); }
Bitwise XOR
operator!(Left, Right: a ^ b -> Answer { Answer(a.0 ^ b.0) }); fn main() { assert_eq!(Left(5) ^ Right(6), Answer(3)); }
Shift-left
operator!(Left, Right: a << b -> Answer { Answer(a.0 << b.0) }); fn main() { assert_eq!(Left(5) << Right(3), Answer(40)); }
Shift-right
operator!(Left, Right: a >> b -> Answer { Answer(a.0 >> b.0) }); fn main() { assert_eq!(Left(43) >> Right(3), Answer(5)); }
Index
#[derive(Debug)] struct Left(Vec<i32>); #[derive(Debug)] struct Right(usize); operator!(Left, Right: a[b] -> &i32 { // The & is required to remind developers that a reference is to be returned. &a.0[b.0] }); fn main() { // We check for 6 not &6, because while the impl returns &6, the [] operator from Rust dereferences it. assert_eq!(Left(vec![5, 6, 7])[Right(1)], 6); }
Macros
operator |