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}