dbn_macros/
lib.rs

1use proc_macro::TokenStream;
2
3mod dbn_attr;
4mod debug;
5mod has_rtype;
6mod py_field_desc;
7mod serialize;
8mod utils;
9
10/// Dummy derive macro to get around `cfg_attr` incompatibility of several
11/// of pyo3's attribute macros. See <https://github.com/PyO3/pyo3/issues/780>.
12///
13/// `MockPyo3` is an invented trait.
14#[proc_macro_derive(MockPyo3, attributes(pyo3))]
15pub fn derive_mock_pyo3(_item: TokenStream) -> TokenStream {
16    TokenStream::new()
17}
18
19/// Dummy derive macro to enable the `dbn` helper attribute for record types
20/// using the `dbn_record` proc macro but neither `CsvSerialize` nor `JsonSerialize` as
21/// helper attributes aren't supported for proc macros alone. See
22/// <https://github.com/rust-lang/rust/issues/65823>.
23#[proc_macro_derive(DbnAttr, attributes(dbn))]
24pub fn dbn_attr(_item: TokenStream) -> TokenStream {
25    TokenStream::new()
26}
27
28/// Derive macro for CSV serialization. Supports the following `dbn` attributes:
29/// - `c_char`: serializes the field as a `char`
30/// - `encode_order`: overrides the position of the field in the CSV table
31/// - `fixed_price`: serializes the field as fixed-price, with the output format
32///   depending on `PRETTY_PX`
33/// - `skip`: does not serialize the field
34/// - `unix_nanos`: serializes the field as a UNIX timestamp, with the output format
35///   depending on `PRETTY_TS`
36///
37/// Note: fields beginning with `_` will automatically be skipped, e.g. `_reserved`
38/// isn't serialized.
39#[proc_macro_derive(CsvSerialize, attributes(dbn))]
40pub fn derive_csv_serialize(input: TokenStream) -> TokenStream {
41    serialize::derive_csv_macro_impl(input)
42}
43
44/// Derive macro for JSON serialization.
45///
46/// Supports the following `dbn` attributes:
47/// - `c_char`: serializes the field as a `char`
48/// - `fixed_price`: serializes the field as fixed-price, with the output format
49///   depending on `PRETTY_PX`
50/// - `skip`: does not serialize the field
51/// - `unix_nanos`: serializes the field as a UNIX timestamp, with the output format
52///   depending on `PRETTY_TS`
53///
54/// Note: fields beginning with `_` will automatically be skipped, e.g. `_reserved`
55/// isn't serialized.
56#[proc_macro_derive(JsonSerialize, attributes(dbn))]
57pub fn derive_json_serialize(input: TokenStream) -> TokenStream {
58    serialize::derive_json_macro_impl(input)
59}
60
61/// Derive macro for field descriptions exposed to Python.
62///
63/// Supports the following `dbn` attributes:
64/// - `c_char`: indicates the field dtype should be a single-character string rather
65///   than an integer
66/// - `encode_order`: overrides the position of the field in the ordered list
67/// - `fixed_price`: indicates this is a fixed-precision field
68/// - `skip`: indicates this field should be hidden
69/// - `unix_nanos`: indicates this is a UNIX nanosecond timestamp field
70#[proc_macro_derive(PyFieldDesc, attributes(dbn))]
71pub fn derive_py_field_desc(input: TokenStream) -> TokenStream {
72    py_field_desc::derive_impl(input)
73}
74
75/// Attribute macro that acts like a derive macro for `Debug` (with customization),
76/// `Record`, `RecordMut`, `HasRType`, `PartialOrd`, and `AsRef<[u8]>`.
77///
78/// Expects 1 or more paths to `u8` constants that are the RTypes associated
79/// with this record.
80///
81/// Supports the following `dbn` attributes:
82/// - `c_char`: format the type as a `char` instead of as a numeric
83/// - `fixed_price`: format the integer as a fixed-precision decimal
84/// - `fmt_binary`: format as a binary
85/// - `fmt_method`: try to format by calling the getter method with the same name as the
86/// - `index_ts`: indicates this field is the primary timestamp for the record
87///   field. If the getter returns an error, the raw field value will be used
88/// - `skip`: won't be included in the `Debug` output
89///
90/// Note: attribute macros don't support helper attributes on their own. If not deriving
91/// `CsvSerialize` or `JsonSerialize`, derive `DbnAttr` to use the `dbn` helper attribute
92/// without a compiler error.
93#[proc_macro_attribute]
94pub fn dbn_record(attr: TokenStream, input: TokenStream) -> TokenStream {
95    has_rtype::attribute_macro_impl(attr, input)
96}
97
98/// Derive macro for Debug representations with the same extensions for DBN records
99/// as `dbn_record`.
100///
101/// Supports the following `dbn` attributes:
102/// - `c_char`: format the type as a `char` instead of as a numeric
103/// - `fixed_price`: format the integer as a fixed-precision decimal
104/// - `fmt_binary`: format as a binary
105/// - `fmt_method`: try to format by calling the getter method with the same name as the
106///   field. If the getter returns an error, the raw field value will be used
107/// - `skip`: won't be included in the `Debug` output
108///
109/// Note: fields beginning with `_` will automatically be skipped, e.g. `_reserved`
110/// isn't included in the `Debug` output.
111#[proc_macro_derive(RecordDebug, attributes(dbn))]
112pub fn derive_record_debug(input: TokenStream) -> TokenStream {
113    debug::derive_impl(input)
114}
115
116#[cfg(test)]
117mod tests {
118    #[test]
119    fn ui() {
120        let t = trybuild::TestCases::new();
121        t.compile_fail("tests/ui/*.rs");
122    }
123}