structable_derive/
lib.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5//     http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// SPDX-License-Identifier: Apache-2.0
14
15//! Most likely you do not want to use this crate directly. It is a helper for the OpenStack
16//!
17//! This crate implements derive macros for converting structures
18//! (or structure vectors) as tables (vector of vector of strings -
19//! as rows and columns).
20//!
21//! ```rust
22//! # use std::collections::BTreeSet;
23//! # use serde_json::Value;
24//! # use serde::Serialize;
25//! # use structable_derive::StructTable;
26//! #
27//! # pub trait StructTable {
28//! #     fn headers<O: StructTableOptions>(config: &O) -> Vec<String>;
29//! #     fn data<O: StructTableOptions>(&self, config: &O) -> Vec<Option<String>>;
30//! #     fn status(&self) -> Option<String>;
31//! # }
32//! #
33//! # #[derive(Clone, Debug, Default)]
34//! # pub struct OutputConfig {
35//! #     pub fields: BTreeSet<String>,
36//! #     pub wide: bool,
37//! #     pub pretty: bool,
38//! # }
39//! #
40//! # pub trait StructTableOptions {
41//! #     fn wide_mode(&self) -> bool;
42//! #     fn pretty_mode(&self) -> bool;
43//! #     fn should_return_field<S: AsRef<str>>(&self, field: S, is_wide_field: bool) -> bool;
44//! # }
45//! #
46//! # impl StructTableOptions for OutputConfig {
47//! #     fn wide_mode(&self) -> bool {
48//! #         self.wide
49//! #     }
50//! #
51//! #     fn pretty_mode(&self) -> bool {
52//! #         self.pretty
53//! #     }
54//! #
55//! #     fn should_return_field<S: AsRef<str>>(&self, field: S, is_wide_field: bool) -> bool {
56//! #         if !is_wide_field {
57//! #             self.fields.is_empty() || self.fields.contains(field.as_ref())
58//! #         } else {
59//! #             (self.fields.is_empty() && self.wide_mode()) || self.fields.contains(field.as_ref())
60//! #         }
61//! #     }
62//! # }
63//! #
64//! #[derive(Serialize, StructTable)]
65//! struct User {
66//!     #[structable(title = "ID")]
67//!     id: u64,
68//!     first_name: &'static str,
69//!     last_name: &'static str,
70//!     #[structable(title = "Long(only in wide mode)", wide)]
71//!     extra: &'static str,
72//!     #[structable(optional, pretty)]
73//!     complex_data: Option<Value>
74//! }
75//! ```
76mod structable;
77
78use darling::FromDeriveInput;
79use quote::quote;
80use syn::{parse_macro_input, DeriveInput};
81
82#[proc_macro_derive(StructTable, attributes(structable))]
83/// Derive macro to implementing `VecTable` traits
84pub fn openstack_result_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
85    // Parse the input tokens into a syntax tree
86    let input = parse_macro_input!(input as DeriveInput);
87
88    let receiver = structable::TableStructInputReceiver::from_derive_input(&input).unwrap();
89    let tokens = quote!(#receiver);
90    tokens.into()
91}