uni_components_macro/
lib.rs

1extern crate proc_macro;
2
3mod define_service;
4mod define_type;
5mod define_ui_page;
6
7use proc_macro::TokenStream;
8
9/// Helps to define new [UiPage](ui_page::UiPage)
10///
11/// ```
12/// define_ui_page!(
13///    name: PAGE_INDEX,
14///    parameter: String,
15///    path: "/",
16/// );
17/// ```
18#[proc_macro]
19pub fn define_ui_page(input: TokenStream) -> TokenStream {
20	return define_ui_page::define_ui_page(input);
21}
22
23/// Helps to define new [Service](service::Service)
24///
25/// The macros generates new module where all Service-related data will be placed.
26///
27/// There will be:
28/// * In -- type alias for Service's input type
29/// * Out -- type alias for Service's output type
30/// (or type itself if `outputs` used instead of `output_type`)
31/// * Struct -- the structure for which [Service] trait will be implemented
32/// * INSTANCE -- const instance of the Struct
33/// * REF -- 'static ref for Struct (pointing to the INSTANCE)
34///
35/// # Parameters
36/// ## `doc` (optional)
37/// String literal which will be used as a documentation for a new module.
38/// The explanation of the service functionality may be placed here.
39///
40/// ## `name` (required)
41/// Identifier (name) for new module.
42///
43/// ## `input` (required)
44/// Service's input type.
45///
46/// Right now for King::Get services you have to use structure or enum (not String or i32
47/// or etc.)
48///
49/// ## `output_type` (one of `output_type` or `outputs` required)
50/// Service's output type. The type has to implement [AsResponse]
51/// and has to have
52/// `pub fn from_response(response: uni_components::::Response) -> Result<Self,
53/// uni_components::Response>` function.
54///
55/// The best way to implement the type is to use [define_type!] macro.
56///
57/// Otherwise you can use `outputs` parameter and skip `output_type`.
58///
59/// ## `outputs` (one of `output_type` or `outputs` required)
60/// There you can specify variants how you do for [define_type!]'s `variants` parameter.
61///
62/// You can not have both `outputs` and `output_type` together.
63///
64/// ## `path` (required)
65/// The path where the service will be available at website.
66///
67/// ## `kind` (required)
68/// Select a kind of your servce. It should be one of [Kind]s.
69///
70/// # Example
71/// ```
72/// define_service!(
73///    doc: "
74///    Authentication service.
75///
76///    It receives user credentials (as a part of authorization request) and
77///    then provides token as a response.
78///    ",
79///    name: AUTH_ACTION,
80///    kind: uni_components::Kind::Post,
81///    input: common::Auth,
82///    outputs: [
83///        AuthorizedToken {
84///            code: 200,
85///            body: String,
86///            doc: "You are authorized to use the service. Token provided"
87///        },
88///        NonAuthorized {
89///            code: 401,
90///            doc: "Non authorized. Probably credentials are incorrect",
91///        },
92///    ],
93///    path: "/api/login/",
94/// );
95/// ```
96#[proc_macro]
97pub fn define_service(input: TokenStream) -> TokenStream {
98	return define_service::define_service(input);
99}
100
101/// Helps to define type for service output
102///
103/// Two parameters have to be specified: `name` and `variants` (`doc` is optional).
104///
105/// # `doc` (optional)
106/// Provide string literal there. It'll be used as doc for the new type.
107///
108/// # `name` (required)
109/// It'll become the name of a new type so any identifier will works.
110/// Generic types may be specified as
111///
112/// ```
113/// //...
114///      name: TypeName<T,K> where T: Send, K: Sync {},
115/// //...
116/// ```
117/// Please take a look at `{}` at the end of the line.
118/// The minimal bound should be
119/// `T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned`.
120///
121/// # `variants` (required)
122/// It looks like array where each element are one possible vairant of service answer:
123/// ```
124/// <VariantName> {
125///     code: <code_value>,
126///     body: <body_type>,
127///     doc: <doc_content>,
128/// }
129/// ```
130/// * <VariantName> will become identifier for the variant,
131/// * <code_value> (required) should be u16 and recommended to be one of allowed
132/// [HTTP codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
133/// * `body` (optional) parameter is optional and <body_type> have to be the type of data
134///   represented by the variant
135/// * `doc` (optional) parameter is optional and <doc_content> have to be string literal,
136///   that literal will be added as documentation to the variant
137///
138/// # Example
139/// ```
140/// define_type!{
141///     doc: "
142///     The type repsersents an answer for the question.
143///
144///     Server may have the answer or may have not.
145///     ",
146///     name: QuestionAnswer,
147///     variants:[
148///         Ok{
149///             code: 200,
150///             body: String,
151///             doc: "Answer found:",
152///         },
153///         NumberNotFound{
154///             code: 404,
155///             doc: "Answer not found",
156///         },
157///     ]
158/// }
159/// ```
160#[proc_macro]
161pub fn define_type(input: TokenStream) -> TokenStream {
162	return define_type::define_type(input);
163}
164
165fn the_crate_name() -> proc_macro2::TokenStream {
166	quote::quote! {
167		uni_components
168	}
169}