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
//! DSL definition
//!
//! ## Components
//!
//! ### Basic use, with variable or expression:
//! ```
//! # use dessin::prelude::*;
//! let r = 2.;
//!
//! dessin!(Circle(
//! radius=r,
//! translate=[r * 2., 0.],
//! ));
//! ```
//!
//! ### With a function that takes no argument:
//!
//! ```
//! # use dessin::prelude::*;
//! dessin!(Curve(
//! closed,
//! ));
//! ```
//!
//! ### With a function that has the same name as a variable:
//!
//! ```
//! # use dessin::prelude::*;
//! let text = "my string";
//! dessin!(Text(
//! {text},
//! ));
//! ```
//!
//! ### With component in a mod:
//!
//! ```
//! # use dessin::prelude::dessin;
//! dessin!(dessin::prelude::Text());
//! ```
//!
//! ## Group
//!
//! ```
//! # use dessin::prelude::*;
//! dessin!([
//! Circle(),
//! Text(),
//! ]);
//! ```
//!
//! ## Erase type
//!
//! Useful to access certain function only availiable in Shape (related to transform).
//! Also useful also for branches with different components (see [If else](#with-different-components)),
//!
//! ```
//! # use dessin::prelude::*;
//! dessin!(Text(
//! // here type is `Text`
//! ) > (
//! // here type is `Shape`
//! ));
//!
//! dessin!([
//! Circle(),
//! Text(),
//! ] > (
//! // Transform this group
//! ));
//! ```
//!
//! ## For loop
//!
//! ```
//! # use dessin::prelude::*;
//! dessin!(for x in 0..10 {
//! // Here, rust code is expected. But return type must be a `Shape`
//! let x = x as f32;
//!
//! dessin!(Circle(
//! radius=x,
//! translate=[x, x * 2.]
//! ))
//! });
//!
//! // Same as before, we can transform the group after
//! dessin!(for text in ["Hello", "World"] {
//! dessin!(Text(
//! { text },
//! ))
//! } > (
//! scale=[2., 2.],
//! ));
//! ```
//!
//! ## If else
//!
//! ```
//! # use dessin::prelude::*;
//! dessin!(if true {
//! Circle()
//! });
//!
//! // Both side must return the same type
//! dessin!(if true {
//! Circle()
//! } else {
//! Circle()
//! });
//!
//! // That's why the type of each branch can be erased
//! dessin!(if true {
//! Circle() > ()
//! } else {
//! Text() > ()
//! });
//! ```