operator_sugar/lib.rs
1// operator-sugar
2// Copyright (C) SOFe
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! This crate provides simple macros that serve as syntactic sugar to make overloading operators
17//! in Rust easier.
18//!
19//! The basic syntax for binary operators is in this format:
20//!
21//! ```
22//! # use operator_sugar::*;
23//! struct Left(i32);
24//! struct Right(i32);
25//! struct Answer(i32);
26//!
27//! operator!(Left, Right: a + b -> Answer {
28//! // Implementation of the operator function here
29//! Answer(a.0 + b.0)
30//! });
31//! ```
32//!
33//! For unary operators:
34//!
35//! ```
36//! # use operator_sugar::*;
37//! struct Operand(i32);
38//! struct Answer(i32);
39//!
40//! operator!(Operand: -a -> Answer {
41//! Answer(-a.0)
42//! });
43//! ```
44//!
45//! # Meta Attributes
46//! Attributes can be applied to the `impl` block (which implements e.g. `Add`) and the `fn` block respectively:
47//!
48//! ```
49//! # use operator_sugar::*;
50//! struct Left(i32);
51//! struct Right(i32);
52//! struct Answer(i32);
53//!
54//! operator!(
55//! #[doc("This attribute will be applied on the `impl` block")] Left, Right:
56//! #[doc("This attribute will be applied on the `fn` block")] a + b -> Answer {
57//! Answer(a.0 + b.0)
58//! });
59//! ```
60//!
61//! # Generics
62//! Generics can be used on the three types and on the `impl` block.
63//!
64//! Due to disambiguation, generic parameters for the `impl` block must be written in `{}` rather
65//! than `<>`.
66//!
67//! ```
68//! # use operator_sugar::*;
69//! use core::ops::Add;
70//! struct Left<T>(T) where T: Add<i32, Output = i32>;
71//! struct Right(i32);
72//! struct Answer(i32);
73//!
74//! operator!(
75//! {T: Add<i32, Output = i32>}
76//! Left<T>, Right: a + b -> Answer {
77//! Answer(a.0 + b.0)
78//! });
79//! ```
80//!
81//! # List of operators
82//! For conciseness, these definitions are defined for each of the following examples:
83//! ```no_run
84//! use operator_sugar::*;
85//! #[derive(Debug)] struct Left(i32);
86//! #[derive(Debug)] struct Right(i32);
87//! #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
88//! ```
89//!
90//! ## Addition
91//! ```
92//! # use operator_sugar::*;
93//! # #[derive(Debug)] struct Left(i32);
94//! # #[derive(Debug)] struct Right(i32);
95//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
96//! #
97//! operator!(Left, Right: a + b -> Answer {
98//! Answer(a.0 + b.0)
99//! });
100//!
101//! fn main() {
102//! assert_eq!(Left(1) + Right(2), Answer(3));
103//! }
104//! ```
105//!
106//! ## Subtraction
107//! ```
108//! # use operator_sugar::*;
109//! # #[derive(Debug)] struct Left(i32);
110//! # #[derive(Debug)] struct Right(i32);
111//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
112//! #
113//! operator!(Left, Right: a - b -> Answer {
114//! Answer(a.0 - b.0)
115//! });
116//!
117//! fn main() {
118//! assert_eq!(Left(1) - Right(2), Answer(-1));
119//! }
120//! ```
121//!
122//! ## Multiplication
123//! ```
124//! # use operator_sugar::*;
125//! # #[derive(Debug)] struct Left(i32);
126//! # #[derive(Debug)] struct Right(i32);
127//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
128//! #
129//! operator!(Left, Right: a * b -> Answer {
130//! Answer(a.0 * b.0)
131//! });
132//!
133//! fn main() {
134//! assert_eq!(Left(3) * Right(2), Answer(6));
135//! }
136//! ```
137//!
138//! ## Division
139//! ```
140//! # use operator_sugar::*;
141//! # #[derive(Debug)] struct Left(i32);
142//! # #[derive(Debug)] struct Right(i32);
143//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
144//! #
145//! operator!(Left, Right: a / b -> Answer {
146//! Answer(a.0 / b.0)
147//! });
148//!
149//! fn main() {
150//! assert_eq!(Left(8) / Right(2), Answer(4));
151//! }
152//! ```
153//!
154//! ## Remainder
155//! ```
156//! # use operator_sugar::*;
157//! # #[derive(Debug)] struct Left(i32);
158//! # #[derive(Debug)] struct Right(i32);
159//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
160//! #
161//! operator!(Left, Right: a % b -> Answer {
162//! Answer(a.0 % b.0)
163//! });
164//!
165//! fn main() {
166//! assert_eq!(Left(9) % Right(5), Answer(4));
167//! }
168//! ```
169//!
170//! ## Bitwise AND
171//! ```
172//! # use operator_sugar::*;
173//! # #[derive(Debug)] struct Left(i32);
174//! # #[derive(Debug)] struct Right(i32);
175//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
176//! #
177//! operator!(Left, Right: a & b -> Answer {
178//! Answer(a.0 & b.0)
179//! });
180//!
181//! fn main() {
182//! assert_eq!(Left(5) & Right(6), Answer(4));
183//! }
184//! ```
185//!
186//! ## Bitwise OR
187//! ```
188//! # use operator_sugar::*;
189//! # #[derive(Debug)] struct Left(i32);
190//! # #[derive(Debug)] struct Right(i32);
191//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
192//! #
193//! operator!(Left, Right: a | b -> Answer {
194//! Answer(a.0 | b.0)
195//! });
196//!
197//! fn main() {
198//! assert_eq!(Left(5) | Right(6), Answer(7));
199//! }
200//! ```
201//!
202//! ## Bitwise XOR
203//! ```
204//! # use operator_sugar::*;
205//! # #[derive(Debug)] struct Left(i32);
206//! # #[derive(Debug)] struct Right(i32);
207//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
208//! #
209//! operator!(Left, Right: a ^ b -> Answer {
210//! Answer(a.0 ^ b.0)
211//! });
212//!
213//! fn main() {
214//! assert_eq!(Left(5) ^ Right(6), Answer(3));
215//! }
216//! ```
217//!
218//! ## Shift-left
219//! ```
220//! # use operator_sugar::*;
221//! # #[derive(Debug)] struct Left(i32);
222//! # #[derive(Debug)] struct Right(i32);
223//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
224//! #
225//! operator!(Left, Right: a << b -> Answer {
226//! Answer(a.0 << b.0)
227//! });
228//!
229//! fn main() {
230//! assert_eq!(Left(5) << Right(3), Answer(40));
231//! }
232//! ```
233//!
234//! ## Shift-right
235//! ```
236//! # use operator_sugar::*;
237//! # #[derive(Debug)] struct Left(i32);
238//! # #[derive(Debug)] struct Right(i32);
239//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
240//! #
241//! operator!(Left, Right: a >> b -> Answer {
242//! Answer(a.0 >> b.0)
243//! });
244//!
245//! fn main() {
246//! assert_eq!(Left(43) >> Right(3), Answer(5));
247//! }
248//! ```
249//!
250//! ## Index
251//! ```
252//! # use operator_sugar::*;
253//! #[derive(Debug)] struct Left(Vec<i32>);
254//! #[derive(Debug)] struct Right(usize);
255//!
256//! operator!(Left, Right: a[b] -> &i32 {
257//! // The & is required to remind developers that a reference is to be returned.
258//! &a.0[b.0]
259//! });
260//!
261//! fn main() {
262//! // We check for 6 not &6, because while the impl returns &6, the [] operator from Rust dereferences it.
263//! assert_eq!(Left(vec![5, 6, 7])[Right(1)], 6);
264//! }
265//! ```
266//!
267//! ## Negative (`-`)
268//! ```
269//! # use operator_sugar::*;
270//! # #[derive(Debug)] struct Left(i32);
271//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
272//!
273//! operator!(Left: -a -> Answer {
274//! Answer(-a.0)
275//! });
276//!
277//! fn main() {
278//! assert_eq!(-Left(43), Answer(-43));
279//! }
280//! ```
281//!
282//! ## Not (`!`)
283//! ```
284//! # use operator_sugar::*;
285//! # #[derive(Debug)] struct Left(i32);
286//! # #[derive(Debug, Eq, PartialEq)] struct Answer(i32);
287//!
288//! operator!(Left: !a -> Answer {
289//! Answer(!a.0)
290//! });
291//!
292//! fn main() {
293//! assert_eq!(!Left(43), Answer(!43));
294//! }
295//! ```
296
297#![no_std]
298
299#[macro_export]
300macro_rules! operator {
301 (
302 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
303 $(#[$fn_attr:meta])* $a:ident + $b:ident -> $C:ty
304 { $($body:tt)* }
305 ) => {
306 $(#[$impl_attr])*
307 impl $(< $($generics)* >)? ::core::ops::Add<$B> for $A {
308 type Output = $C;
309
310 $(#[$fn_attr])*
311 fn add(self, $b: $B) -> Self::Output {
312 let $a = self;
313 $($body)*
314 }
315 }
316 };
317
318 (
319 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
320 $(#[$fn_attr:meta])* $a:ident - $b:ident -> $C:ty
321 { $($body:tt)* }
322 ) => {
323 $(#[$impl_attr])*
324 impl $(< $($generics)* >)? ::core::ops::Sub<$B> for $A {
325 type Output = $C;
326
327 $(#[$fn_attr])*
328 fn sub(self, $b: $B) -> Self::Output {
329 let $a = self;
330 $($body)*
331 }
332 }
333 };
334
335 (
336 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
337 $(#[$fn_attr:meta])* $a:ident * $b:ident -> $C:ty
338 { $($body:tt)* }
339 ) => {
340 $(#[$impl_attr])*
341 impl $(< $($generics)* >)? ::core::ops::Mul<$B> for $A {
342 type Output = $C;
343
344 $(#[$fn_attr])*
345 fn mul(self, $b: $B) -> Self::Output {
346 let $a = self;
347 $($body)*
348 }
349 }
350 };
351
352 (
353 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
354 $(#[$fn_attr:meta])* $a:ident / $b:ident -> $C:ty
355 { $($body:tt)* }
356 ) => {
357 $(#[$impl_attr])*
358 impl $(< $($generics)* >)? ::core::ops::Div<$B> for $A {
359 type Output = $C;
360
361 $(#[$fn_attr])*
362 fn div(self, $b: $B) -> Self::Output {
363 let $a = self;
364 $($body)*
365 }
366 }
367 };
368
369 (
370 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
371 $(#[$fn_attr:meta])* $a:ident % $b:ident -> $C:ty
372 { $($body:tt)* }
373 ) => {
374 $(#[$impl_attr])*
375 impl $(< $($generics)* >)? ::core::ops::Rem<$B> for $A {
376 type Output = $C;
377
378 $(#[$fn_attr])*
379 fn rem(self, $b: $B) -> Self::Output {
380 let $a = self;
381 $($body)*
382 }
383 }
384 };
385
386 (
387 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
388 $(#[$fn_attr:meta])* $a:ident & $b:ident -> $C:ty
389 { $($body:tt)* }
390 ) => {
391 $(#[$impl_attr])*
392 impl $(< $($generics)* >)? ::core::ops::BitAnd<$B> for $A {
393 type Output = $C;
394
395 $(#[$fn_attr])*
396 fn bitand(self, $b: $B) -> Self::Output {
397 let $a = self;
398 $($body)*
399 }
400 }
401 };
402
403 (
404 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
405 $(#[$fn_attr:meta])* $a:ident | $b:ident -> $C:ty
406 { $($body:tt)* }
407 ) => {
408 $(#[$impl_attr])*
409 impl $(< $($generics)* >)? ::core::ops::BitOr<$B> for $A {
410 type Output = $C;
411
412 $(#[$fn_attr])*
413 fn bitor(self, $b: $B) -> Self::Output {
414 let $a = self;
415 $($body)*
416 }
417 }
418 };
419
420 (
421 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
422 $(#[$fn_attr:meta])* $a:ident ^ $b:ident -> $C:ty
423 { $($body:tt)* }
424 ) => {
425 $(#[$impl_attr])*
426 impl $(< $($generics)* >)? ::core::ops::BitXor<$B> for $A {
427 type Output = $C;
428
429 $(#[$fn_attr])*
430 fn bitxor(self, $b: $B) -> Self::Output {
431 let $a = self;
432 $($body)*
433 }
434 }
435 };
436
437 (
438 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
439 $(#[$fn_attr:meta])* $a:ident << $b:ident -> $C:ty
440 { $($body:tt)* }
441 ) => {
442 $(#[$impl_attr])*
443 impl $(< $($generics)* >)? ::core::ops::Shl<$B> for $A {
444 type Output = $C;
445
446 $(#[$fn_attr])*
447 fn shl(self, $b: $B) -> Self::Output {
448 let $a = self;
449 $($body)*
450 }
451 }
452 };
453
454 (
455 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
456 $(#[$fn_attr:meta])* $a:ident >> $b:ident -> $C:ty
457 { $($body:tt)* }
458 ) => {
459 $(#[$impl_attr])*
460 impl $(< $($generics)* >)? ::core::ops::Shr<$B> for $A {
461 type Output = $C;
462
463 $(#[$fn_attr])*
464 fn shr(self, $b: $B) -> Self::Output {
465 let $a = self;
466 $($body)*
467 }
468 }
469 };
470
471 (
472 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty, $B:ty :
473 $(#[$fn_attr:meta])* $a:ident[$b:ident] -> & $C:ty
474 { $($body:tt)* }
475 ) => {
476 $(#[$impl_attr])*
477 impl $(< $($generics)* >)? ::core::ops::Index<$B> for $A {
478 type Output = $C;
479
480 $(#[$fn_attr])*
481 fn index(&self, $b: $B) -> &Self::Output {
482 let $a = self;
483 $($body)*
484 }
485 }
486 };
487
488 (
489 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty :
490 $(#[$fn_attr:meta])* -$a:ident -> $C:ty
491 { $($body:tt)* }
492 ) => {
493 $(#[$impl_attr])*
494 impl $(< $($generics)* >)? ::core::ops::Neg for $A {
495 type Output = $C;
496
497 $(#[$fn_attr])*
498 fn neg(self) -> Self::Output {
499 let $a = self;
500 $($body)*
501 }
502 }
503 };
504
505 (
506 $(#[$impl_attr:meta])* $({ $($generics:tt)* })? $A:ty :
507 $(#[$fn_attr:meta])* !$a:ident -> $C:ty
508 { $($body:tt)* }
509 ) => {
510 $(#[$impl_attr])*
511 impl $(< $($generics)* >)? ::core::ops::Not for $A {
512 type Output = $C;
513
514 $(#[$fn_attr])*
515 fn not(self) -> Self::Output {
516 let $a = self;
517 $($body)*
518 }
519 }
520 };
521}