1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//! # Appy - Declarative UI Framework for Native Application
//!
//! This crate contains macros for [Appy](https://github.com/limikael/appy).
//!
//! It is published as a separate crate  due to technical reasons. See
//! this [stack overflow thread](https://stackoverflow.com/questions/56713877/why-do-proc-macros-have-to-be-defined-in-proc-macro-crate).
//!
//! If it is not the case any more that it needs to be separate, please let me know!
use proc_macro::{*};

mod main_window;
#[proc_macro_attribute]
/// Application entry point.
///
/// The main window macro defines the main application entry point.
/// It should be placed on a function that returns Elements. In this
/// sense, it is similar to the render function of an Element, but it
/// does not take any properties or children.
///
/// # Example
/// ```rust
/// use appy::*;
///
/// #[main_window]
/// pub fn app()->Elements {
///    apx!{
///        <bg col=0x800000/>
///        <text text="Hello World".to_string() align=Align::Center/>
///    }
/// }
/// ```
pub fn main_window(attr: TokenStream, input: TokenStream) -> TokenStream {
	main_window::main_window(attr,input)
}

mod derive_component;
/// Create a component.
///
/// A component takes input in the form of props and children,
/// and return elements describing what should appear on the screen.
///
/// # Example
/// ```rust
/// #[derive_component(Default,ComponentBuilder)]
/// pub struct MyComp {
///   param1: i32,
///   param2: i32
/// }
///
/// impl Element for MyComp {
///   pub fn render(self: ElementWrap<Self>)->Elements {
///     apx! {
///       <bg col=0x000000/>
///     }
///   }
/// }
/// ```
///
/// The component declared above can be used together with the
/// apx macro:
/// ```rust
/// apx!{
///   <MyComp param1=123 param2=456/>
///	}
/// ```
#[proc_macro_attribute]
pub fn derive_component(attr: TokenStream, input: TokenStream) -> TokenStream {
	derive_component::derive_component(attr,input)
}

mod component_builder;
/// Create builder.
///
/// Create a builder implementation. For example, when placed on the following struct:
/// ```rust
/// struct MyStruct {
///     an_int:i32,
///     an_optional_string:Option<String>
/// }
/// ```
/// This macro will create the following implementation:
/// ```rust
/// impl MyStruct {
///     pub fn new()->ElementWrap<Self> {
///         // ...
///     }
///
///     pub fn an_int(ElementWrap<Self>,v:i32)->ElementWrap<Self> {
///         // ...
///     }
///
///     pub fn an_optional_string(ElementWrap<Self>,v:String)->ElementWrap<Self> {
///         // ...
///     }
///	}
/// ```
/// Notes:
/// - For optional properties, e.g. fields wrapped in `Option<...>`, the setter in
///   the builder will take the wrapped type as parameter and call `Some()` with the
///   value.
#[proc_macro_derive(ComponentBuilder)]
pub fn component_builder(input: TokenStream) -> TokenStream {
	component_builder::component_builder(input)
}

mod snake_factory;
/// Produce snake cased factory function.
///
/// When placed on a `struct`, e.g. `MyStruct`, this derive macro
/// will create a function `my_struct` defined as:
/// ```rust
/// fn my_struct() -> MyStruct {
///     MyStruct::new()
/// }
/// ```
#[proc_macro_derive(SnakeFactory)]
pub fn snake_factory(input: TokenStream) -> TokenStream {
	snake_factory::snake_factory(input)
}

mod apx;
/// Process element fragment.
///
/// This macro takes XML, and produces an element fragment represented as
/// `Elements`. For example, the following APX snippet:
/// ```rust
/// apx!{
///     <my_component param1=123 param2=456/>
///	}
/// ```
/// Is syntactical sugar for the following:
/// ```rust
/// vec![
///     my_component().param1(123).param3(456)
/// ]
/// ```
/// And it would be used together with a component defined like this:
/// ```rust
/// #[derive_component(ComponentBuilder,Default,SnakeFactory)]
/// pub struct MyComponent {
///     param1: i32,
///     param2: i32
/// }
///
/// impl Element for MyComponent {
///     fn render(self:ElementWrap<Self>)->Elements {
///         // ...
///     }
/// }
#[proc_macro]
pub fn apx(input: TokenStream) -> TokenStream {
	apx::apx(input)
}