nu_derive_value/
lib.rs

1//! Macro implementations of `#[derive(FromValue, IntoValue)]`.
2//!
3//! As this crate is a [`proc_macro`] crate, it is only allowed to export
4//! [procedural macros](https://doc.rust-lang.org/reference/procedural-macros.html).
5//! Therefore, it only exports [`IntoValue`] and [`FromValue`].
6//!
7//! To get documentation for other functions and types used in this crate, run
8//! `cargo doc -p nu-derive-value --document-private-items`.
9//!
10//! This crate uses a lot of
11//! [`proc_macro2::TokenStream`](https://docs.rs/proc-macro2/1.0.24/proc_macro2/struct.TokenStream.html)
12//! as `TokenStream2` to allow testing the behavior of the macros directly, including the output
13//! token stream or if the macro errors as expected.
14//! The tests for functionality can be found in `nu_protocol::value::test_derive`.
15//!
16//! This documentation is often less reference-heavy than typical Rust documentation.
17//! This is because this crate is a dependency for `nu_protocol`, and linking to it would create a
18//! cyclic dependency.
19//! Also all examples in the documentation aren't tested as this crate cannot be compiled as a
20//! normal library very easily.
21//! This might change in the future if cargo allows building a proc-macro crate differently for
22//! `cfg(doctest)` as they are already doing for `cfg(test)`.
23//!
24//! The generated code from the derive macros tries to be as
25//! [hygienic](https://doc.rust-lang.org/reference/macros-by-example.html#hygiene) as possible.
26//! This ensures that the macro can be called anywhere without requiring specific imports.
27//! This results in obtuse code, which isn't recommended for manual, handwritten Rust
28//! but ensures that no other code may influence this generated code or vice versa.
29
30use proc_macro::TokenStream;
31use proc_macro_error2::{Diagnostic, proc_macro_error};
32use proc_macro2::TokenStream as TokenStream2;
33
34mod attributes;
35mod case;
36mod error;
37mod from;
38mod into;
39mod names;
40#[cfg(test)]
41mod tests;
42
43const HELPER_ATTRIBUTE: &str = "nu_value";
44
45/// Derive macro generating an impl of the trait `IntoValue`.
46///
47/// For further information, see the docs on the trait itself.
48#[proc_macro_derive(IntoValue, attributes(nu_value))]
49#[proc_macro_error]
50pub fn derive_into_value(input: TokenStream) -> TokenStream {
51    let input = TokenStream2::from(input);
52    let output = match into::derive_into_value(input) {
53        Ok(output) => output,
54        Err(e) => Diagnostic::from(e).abort(),
55    };
56    TokenStream::from(output)
57}
58
59/// Derive macro generating an impl of the trait `FromValue`.
60///
61/// For further information, see the docs on the trait itself.
62#[proc_macro_derive(FromValue, attributes(nu_value))]
63#[proc_macro_error]
64pub fn derive_from_value(input: TokenStream) -> TokenStream {
65    let input = TokenStream2::from(input);
66    let output = match from::derive_from_value(input) {
67        Ok(output) => output,
68        Err(e) => Diagnostic::from(e).abort(),
69    };
70    TokenStream::from(output)
71}