├── .gitignore
├── .vscode
└── settings.json
├── Cargo.lock
├── Cargo.toml
├── LICENSE-APACHE.md
├── LICENSE-MIT.md
├── README.md
├── crates
├── constructivism_macro
│ ├── Cargo.toml
│ ├── LICENSE-APACHE.md
│ ├── LICENSE-MIT.md
│ ├── README.md
│ └── src
│ │ └── lib.rs
├── constructivism_macro_gen
│ ├── Cargo.toml
│ ├── LICENSE-APACHE.md
│ ├── LICENSE-MIT.md
│ ├── README.md
│ └── src
│ │ ├── constructivism_macro.include
│ │ └── lib.rs
└── constructivist
│ ├── Cargo.toml
│ ├── LICENSE-APACHE.md
│ ├── LICENSE-MIT.md
│ ├── README.md
│ └── src
│ ├── context.rs
│ ├── core.include
│ ├── derive.rs
│ ├── exts.rs
│ ├── genlib.rs
│ ├── lib.rs
│ ├── proc.rs
│ └── throw.rs
├── examples
├── props.rs
├── stranger
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
└── tutorial.rs
└── src
├── core.rs
└── lib.rs
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "genlib",
4 | "getset",
5 | "impls",
6 | "rustfmt"
7 | ]
8 | }
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "constructivism"
7 | version = "0.3.0"
8 | dependencies = [
9 | "constructivism_macro",
10 | "tuple_utils",
11 | ]
12 |
13 | [[package]]
14 | name = "constructivism_macro"
15 | version = "0.3.0"
16 | dependencies = [
17 | "constructivist",
18 | "proc-macro2",
19 | "quote",
20 | "syn",
21 | "toml",
22 | ]
23 |
24 | [[package]]
25 | name = "constructivism_macro_gen"
26 | version = "0.3.0"
27 | dependencies = [
28 | "quote",
29 | "syn",
30 | ]
31 |
32 | [[package]]
33 | name = "constructivist"
34 | version = "0.3.0"
35 | dependencies = [
36 | "constructivism_macro_gen",
37 | "proc-macro2",
38 | "quote",
39 | "syn",
40 | "toml",
41 | ]
42 |
43 | [[package]]
44 | name = "equivalent"
45 | version = "1.0.1"
46 | source = "registry+https://github.com/rust-lang/crates.io-index"
47 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
48 |
49 | [[package]]
50 | name = "hashbrown"
51 | version = "0.14.0"
52 | source = "registry+https://github.com/rust-lang/crates.io-index"
53 | checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
54 |
55 | [[package]]
56 | name = "indexmap"
57 | version = "2.0.0"
58 | source = "registry+https://github.com/rust-lang/crates.io-index"
59 | checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
60 | dependencies = [
61 | "equivalent",
62 | "hashbrown",
63 | ]
64 |
65 | [[package]]
66 | name = "memchr"
67 | version = "2.6.3"
68 | source = "registry+https://github.com/rust-lang/crates.io-index"
69 | checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
70 |
71 | [[package]]
72 | name = "proc-macro2"
73 | version = "1.0.67"
74 | source = "registry+https://github.com/rust-lang/crates.io-index"
75 | checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
76 | dependencies = [
77 | "unicode-ident",
78 | ]
79 |
80 | [[package]]
81 | name = "quote"
82 | version = "1.0.33"
83 | source = "registry+https://github.com/rust-lang/crates.io-index"
84 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
85 | dependencies = [
86 | "proc-macro2",
87 | ]
88 |
89 | [[package]]
90 | name = "serde"
91 | version = "1.0.188"
92 | source = "registry+https://github.com/rust-lang/crates.io-index"
93 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
94 | dependencies = [
95 | "serde_derive",
96 | ]
97 |
98 | [[package]]
99 | name = "serde_derive"
100 | version = "1.0.188"
101 | source = "registry+https://github.com/rust-lang/crates.io-index"
102 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
103 | dependencies = [
104 | "proc-macro2",
105 | "quote",
106 | "syn",
107 | ]
108 |
109 | [[package]]
110 | name = "serde_spanned"
111 | version = "0.6.3"
112 | source = "registry+https://github.com/rust-lang/crates.io-index"
113 | checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
114 | dependencies = [
115 | "serde",
116 | ]
117 |
118 | [[package]]
119 | name = "stranger"
120 | version = "0.1.0"
121 |
122 | [[package]]
123 | name = "syn"
124 | version = "2.0.37"
125 | source = "registry+https://github.com/rust-lang/crates.io-index"
126 | checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
127 | dependencies = [
128 | "proc-macro2",
129 | "quote",
130 | "unicode-ident",
131 | ]
132 |
133 | [[package]]
134 | name = "toml"
135 | version = "0.7.8"
136 | source = "registry+https://github.com/rust-lang/crates.io-index"
137 | checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
138 | dependencies = [
139 | "serde",
140 | "serde_spanned",
141 | "toml_datetime",
142 | "toml_edit",
143 | ]
144 |
145 | [[package]]
146 | name = "toml_datetime"
147 | version = "0.6.3"
148 | source = "registry+https://github.com/rust-lang/crates.io-index"
149 | checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
150 | dependencies = [
151 | "serde",
152 | ]
153 |
154 | [[package]]
155 | name = "toml_edit"
156 | version = "0.19.15"
157 | source = "registry+https://github.com/rust-lang/crates.io-index"
158 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
159 | dependencies = [
160 | "indexmap",
161 | "serde",
162 | "serde_spanned",
163 | "toml_datetime",
164 | "winnow",
165 | ]
166 |
167 | [[package]]
168 | name = "tuple_utils"
169 | version = "0.4.0"
170 | source = "registry+https://github.com/rust-lang/crates.io-index"
171 | checksum = "cffaaf9392ef73cd30828797152476aaa2fa37a17856934fa63d4843f34290e9"
172 |
173 | [[package]]
174 | name = "unicode-ident"
175 | version = "1.0.11"
176 | source = "registry+https://github.com/rust-lang/crates.io-index"
177 | checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
178 |
179 | [[package]]
180 | name = "winnow"
181 | version = "0.5.15"
182 | source = "registry+https://github.com/rust-lang/crates.io-index"
183 | checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
184 | dependencies = [
185 | "memchr",
186 | ]
187 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "constructivism"
3 | version = "0.3.0"
4 | edition = "2021"
5 | license = "MIT OR Apache-2.0"
6 | readme = "README.md"
7 | description = "Simplify the construction of structured data."
8 | homepage = "https://github.com/polako-rs/constructivism"
9 | repository = "https://github.com/polako-rs/constructivism"
10 |
11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12 |
13 | [workspace]
14 | members = [
15 | "crates/constructivism_macro",
16 | "crates/constructivism_macro",
17 | "crates/constructivism_macro_gen",
18 |
19 | "examples/stranger",
20 | ]
21 |
22 | [dependencies]
23 | constructivism_macro = { path = "crates/constructivism_macro", version = "0.3.0"}
24 | tuple_utils = "0.4.0"
25 |
--------------------------------------------------------------------------------
/LICENSE-APACHE.md:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
--------------------------------------------------------------------------------
/LICENSE-MIT.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Introduction
2 |
3 | `constructivism` is a Rust sample-library designed to simplify the construction of structured data by defining and manipulating sequences of Constructs. This README provides an overview of how to use `constructivism` and how it can be inlined into you project using `constructivist` library.
4 |
5 | ## Installation
6 |
7 | To use Constructivism in your Rust project, add it as a dependency in your `Cargo.toml` file:
8 |
9 | ```toml
10 | [dependencies]
11 | constructivism = "0.0.2"
12 | ```
13 |
14 | Or let the cargo do the stuff:
15 |
16 | ```bash
17 | cargo add constructivism
18 | ```
19 |
20 | Constructivism can be inlined into you library as for example `your_library_constructivism` within `constructivist` crate. See [instructions](./crates/constructivist).
21 |
22 | ## Guide
23 |
24 | See also [examples/tutorial.rs](examples/tutorial.rs)
25 |
26 | ### Getting Started
27 |
28 | Usually you start with
29 |
30 | ```rust
31 | use constructivism::*;
32 | ```
33 |
34 | ### Constructs and Sequences
35 |
36 | 1.1. **Constructs**: Constructivism revolves around the concept of Constructs. You can derive construct like this:
37 |
38 | ```rust
39 | #[derive(Construct)]
40 | pub struct Node {
41 | hidden: bool,
42 | position: (f32, f32),
43 | }
44 | ```
45 |
46 | 1.2 **`construct!`**: You can use the `construct!` macro to create instances of Constructs. Please ***note*** the dots at the beginning of the each param, they are required and you will find this syntax quite useful.
47 |
48 | ```rust
49 | fn create_node() {
50 | let node = construct!(Node {
51 | .position: (10., 10.),
52 | .hidden: true
53 | });
54 | assert_eq!(node.position.0, 10.);
55 | assert_eq!(node.hidden, true);
56 | }
57 | ```
58 |
59 | 1.3 **Sequences**: A Construct can be declared only in front of another Construct. `constructivism` comes with only Nothing, () construct. The `Self -> Base` relation called Sequence in `constructivism`. You can omit the Sequence declaration, `Self -> Nothing` used in this case. If you want to derive Construct on the top of another meaningful Construct, you have to specify Sequence directly with `#[construct(/* Sequence */)]` attribute.
60 |
61 | ```rust
62 | #[derive(Construct)]
63 | #[construct(Rect -> Node)]
64 | pub struct Rect {
65 | size: (f32, f32),
66 | }
67 | ```
68 |
69 | 1.4 **Constructing Sequences**: The Sequence for the Rect in example above becomes `Rect -> Node -> Nothing`. You can `construct!` the entire sequence within a single call:
70 |
71 | ```rust
72 | fn create_sequence() {
73 | let (rect, node /* nothing */) = construct!(Rect {
74 | .hidden, // You can write just `.hidden` instead of `.hidden: true`
75 | .position: (10., 10.),
76 | .size: (10., 10.),
77 | });
78 | assert_eq!(rect.size.0, 10.);
79 | assert_eq!(node.position.1, 10.);
80 | assert_eq!(node.hidden, false);
81 | }
82 | ```
83 |
84 | 1.5 **Params**: There are different kind of Params (the things you passing to `construct!(..)`):
85 | - Common: use `Default::default()` if not passed to `construct!(..)`
86 | - Default: use provided value if not passed to `construct!(..)`
87 | - Required: must be passed to `construct!(..)`
88 | - Skip: can't be passed to `construct!(..)`, use Default::default() or provided value
89 | You configure behavior using `#[param]` attribute when deriving:
90 |
91 |
92 | ```rust
93 | #[derive(Construct)]
94 | #[construct(Follow -> Node)]
95 | pub struct Follow {
96 | offset: (f32, f32), // Common, no #[param]
97 |
98 | #[param(required)] // Required
99 | target: Entity,
100 |
101 | #[param(default = Anchor::Center)] // Default
102 | anchor: Anchor,
103 |
104 | #[param(skip)] // Skip with Default::default()
105 | last_computed_distance: f32,
106 |
107 | #[param(skip = FollowState::None)] // Skip with provided value
108 | state: FollowState,
109 | }
110 |
111 | #[derive(PartialEq, Debug, Copy, Clone)]
112 | pub struct Entity;
113 |
114 | pub enum Anchor {
115 | Left,
116 | Center,
117 | Right,
118 | }
119 |
120 | pub enum FollowState {
121 | None,
122 | Initialized(f32)
123 | }
124 | ```
125 |
126 | 1.6 **Passing params**: When passing params to `construct!(..)` you have to pass all required for Sequence params, or you will get the compilation error. You can omit non-required params.
127 |
128 | ```rust
129 | fn create_elements() {
130 | // omit everything, default param values will be used
131 | let (rect, node, /* nothing */) = construct!(Rect);
132 | assert_eq!(node.hidden, false);
133 | assert_eq!(rect.size.0, 0.);
134 |
135 | // you have to pass target to Follow, the rest can be omitted..
136 | let (follow, node) = construct!(Follow {
137 | .target: Entity
138 | });
139 | assert_eq!(follow.offset.0, 0.);
140 | assert_eq!(node.hidden, false);
141 |
142 | // ..or specified:
143 | let (follow, node) = construct!(Follow {
144 | .hidden,
145 | .target: Entity,
146 | .offset: (10., 10.),
147 |
148 | // last_computed_distance param is skipped, uncommenting
149 | // the next line will result in compilation error
150 | // error: no field `last_computed_distance` on type `&follow_construct::Params`
151 |
152 | // .last_computed_distance: 10.
153 | });
154 | assert_eq!(follow.offset.0, 10.);
155 | assert_eq!(node.hidden, true);
156 | }
157 | ```
158 |
159 | ### Design and Methods
160 |
161 | 2.1 **Designs and Methods**: Every Construct has its own Design. You can implement methods for a Construct's design:
162 |
163 | ```rust
164 | impl NodeDesign {
165 | pub fn move_to(&self, entity: Entity, position: (f32, f32)) { }
166 | }
167 |
168 | impl RectDesign {
169 | pub fn expand_to(&self, entity: Entity, size: (f32, f32)) { }
170 | }
171 | ```
172 |
173 | 2.2 **Calling Methods**: You can call methods on a Construct's design. Method resolution follows the sequence order:
174 |
175 | ```rust
176 | fn use_design() {
177 | let rect_entity = Entity;
178 | design!(Rect).expand_to(rect_entity, (10., 10.));
179 | design!(Rect).move_to(rect_entity, (10., 10.)); // move_to implemented for NodeDesign
180 | }
181 | ```
182 |
183 | ### Segments
184 |
185 | 3.1 **Segments**: Segments allow you to define and insert segments into a Construct's sequence:
186 |
187 | ```rust
188 | #[derive(Segment)]
189 | pub struct Input {
190 | disabled: bool,
191 | }
192 |
193 | #[derive(Construct)]
194 | #[construct(Button -> Input -> Rect)]
195 | pub struct Button {
196 | pressed: bool
197 | }
198 | ```
199 |
200 | 3.2 **Sequence with Segments**: The Sequence for Button becomes `Button -> Input -> Rect -> Node -> Nothing`. You can instance the entire sequence of a Construct containing segments within a single `construct!` call:
201 |
202 | ```rust
203 | fn create_button() {
204 | let (button, input, rect, node) = construct!(Button {
205 | .disabled: true
206 | });
207 | assert_eq!(button.pressed, false);
208 | assert_eq!(input.disabled, true);
209 | assert_eq!(rect.size.0, 100.);
210 | assert_eq!(node.position.0, 0.);
211 | }
212 | ```
213 |
214 | 3.3 **Segment Design**: Segment has its own Design as well. And the method call resolves within the Sequence order as well. Segment's designs has one generic parameter - the next segment/construct, so you have to respect it when implement Segment's Design:
215 |
216 | ```rust
217 | impl InputDesign {
218 | fn focus(&self, entity: Entity) {
219 | /* do the focus stuff */
220 | }
221 | }
222 |
223 | fn focus_button() {
224 | let btn = Entity;
225 | design!(Button).focus(btn);
226 | }
227 | ```
228 |
229 | ### Props
230 |
231 | 4.1 **Props**: By deriving Constructs or Segments you also get the ability to set and get properties on items with respect of Sequence:
232 |
233 | ```rust
234 | fn button_props() {
235 | let (mut button, mut input, mut rect, mut node) = construct!(Button);
236 |
237 | // You can access to props knowing only the top-level Construct
238 | let pos /* Prop */ = prop!(Button.position);
239 | let size /* Prop */ = prop!(Button.size);
240 | let disabled /* Prop */ = prop!(Button.disabled);
241 | let pressed /* Prop