beaumont_macros/lib.rs
1#![deny(missing_docs)]
2//!
3//! A collection of procedural macros for the beaumont crates.
4//!
5//! <div class="warning">This crate is in an early stage of development and
6//! <strong>not</strong> production ready yet.<br>Use with caution!</div>
7//!
8
9use proc_macro::TokenStream;
10use syn::parse_macro_input;
11
12// The inner implementation of the literal macro
13mod decimals;
14
15/// Allow custom literals of `Decimal` numbers
16///
17/// Useful for creating decimal numbers the way you would normally create integer or floating
18/// numbers, but appending the custom `d` suffix to the literal (instead of the `i32` or `f32`
19/// usual suffixes). Also, useful for creating decimal numbers from string literals, still by appending the
20/// custom `d` suffix instead of explicitly invoking a parser.
21///
22/// # Examples
23/// ```ignore
24/// use beaumont_numbers::Decimal;
25/// use beaumont_macros::decimals;
26///
27/// #[allow_decimals]
28/// fn do_something() {
29/// // Create a decimal number from integer literals
30/// let d1 = 12d;
31///
32/// // Create a decimal number from float literals
33/// let d2 = 12.00d;
34/// let d3 = -56712.3489d;
35///
36/// // Create a decimal number from string literals
37/// let d4 = "190928.05"d;
38/// }
39/// ```
40///
41/// # Unhygienic
42/// This macro is unhygienic, as it depends on the presence of the `Decimal` local name, referring
43/// to any type for which an implementation of the `std::str::FromStr` trait exists.
44/// While you can bring any `Decimal` you like, you're recommended to bring it as follows:
45///
46/// 1. either by using `beaumont_number::Decimal`,
47/// 2. or by using `beaumont::Decimal` (which is a re-export of the same).
48///
49#[proc_macro_attribute]
50pub fn allow_decimals(_attr: TokenStream, item: TokenStream) -> TokenStream {
51 decimals::transform(parse_macro_input!(item)).into()
52}
53
54
55mod vector;
56
57/// Create mathematical `Vector` from fixed-size array
58///
59/// # Unhygienic
60/// This macro is unhygienic, as it depends on the presence of the `Vector` local name, referring
61/// to any type for which an implementation of `core::convert::From<Box[A]>` trait exists.
62/// While you can bring any `Vector` you wish, you're recommended to bring it as follows:
63///
64/// 1. either by using `beaumont_liner_algebra::Vector`,
65/// 2. or by using `beaumont::Vector` (which is a re-export of the same).
66///
67/// Moreover, this macro can transform decimal literals (those ending with the `d` prefix)
68/// without the need to annotate your functions with the `allow_decimals` macro.
69///
70/// # Examples
71/// ```ignore
72/// use beaumont_macros::vector;
73/// use beaumont_numbers::Decimal;
74/// use beaumont_linear_algebra::Vector;
75///
76/// let v: Vector<Decimal> = vector![1.0d, 2.0d, 3.0d];
77/// assert_eq!(v.len(), 3);
78/// ```
79#[proc_macro]
80pub fn vector(item: TokenStream) -> TokenStream {
81 vector::transform(parse_macro_input!(item)).into()
82}