compris_macros/
lib.rs

1// https://stackoverflow.com/a/61417700
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![warn(missing_docs)]
4
5/*!
6A Rust library to work with CPS (Composite Primitive Schema) data and parse it from and serialize
7it to several binary and textual representation formats, such as YAML, JSON, and CBOR.
8
9A useful side effect of this bi-direction is that Compris can be used to convert between these
10formats.
11
12What is CPS? It's the implicit, common data schema underlying these representation formats. It
13comprises primitive data types (numbers, booleans, strings, etc.) as well as list and map
14collection types, which enable a nested (recursive) structure. Hence it is "composite" (a.k.a.
15"algebraic").
16
17And yet despite being so widely used, CPS has been unnamed... until now. You're welcome.
18
19CPS is sometimes glossed as "JSON", but that's misleading and ultimately unhelpful because JSON is
20merely one representation format for the data, and is actually comparatively quite limited (e.g.
21implementations do not often preserve the distinction between integers and floats). So instead of
22saying "let's just store it as JSON", say "let's just store it as CPS", and use Compris to handle
23the representation. It will allow you and your users to select from all supported formats at
24runtime.
25
26Compris is pronounced "com-PREE". The name comes from shortening CompositePrimitiveSchema to
27ComPriS.
28
29For more information and usage examples see the
30[home page](https://github.com/tliron/compris).
31
32J'ai compris!
33*/
34
35mod derive_resolve;
36mod utils;
37
38use derive_resolve::*;
39
40// See: https://petanode.com/posts/rust-proc-macro/
41
42/// Procedural macro for `#[derive(Resolve)]`.
43#[proc_macro_derive(Resolve, attributes(resolve))]
44pub fn derive_resolve(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
45    let mut input: syn::DeriveInput = syn::parse_macro_input!(input);
46
47    match input.data {
48        syn::Data::Struct(_) => StructGenerator::generate(&mut input),
49
50        syn::Data::Enum(_) => EnumGenerator::generate(&mut input),
51
52        _ => Err(syn::Error::new(input.ident.span(), "`Resolve`: not a struct or an enum")),
53    }
54    .unwrap_or_else(|e| e.to_compile_error())
55    .into()
56}