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}