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)
}