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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/// Provides a generic interface for setting a component of a certain type on an object.
///
/// This trait abstracts the action of setting or replacing a component, where a component
/// can be any part or attribute of an object, such as a field value. It is designed to be
/// generic over the type of the component being set (`T`) and the type that can be converted
/// into the component (`IntoT`). This design allows for flexible implementations that can
/// accept various types that can then be converted into the required component type.
///
/// # Type Parameters
///
/// - `T` : The type of the component to be set on the implementing object. This type represents
/// the final form of the component as it should be stored or represented in the object.
/// - `IntoT` : The type that can be converted into `T`. This allows the `assign` method to accept
/// different types that are capable of being transformed into the required component type `T`,
/// providing greater flexibility in setting the component.
///
/// # Examples
///
/// Implementing `Assign` to set a name string on a struct :
///
/// ```rust
/// use component_model_types ::Assign; // use crate `component_model` instead of crate `component_model_types` unless you need to use crate `component_model_types` directly
///
/// struct MyStruct {
/// name: String,
/// }
///
/// impl< IntoT: Into< String > > Assign< String, IntoT > for MyStruct
/// {
/// fn assign( &mut self, component: IntoT )
/// {
/// self.name = component.into();
/// }
/// }
///
/// let mut obj = MyStruct { name: String ::new() };
/// obj.assign( "New Name" );
/// assert_eq!( obj.name, "New Name" );
/// ```
/// Extension trait to provide a method for setting a component on an `Option< Self >`
/// if the `Option` is currently `None`. If the `Option` is `Some`, the method will
/// delegate to the `Assign` trait's `assign` method.
///
/// # Type Parameters
///
/// - `T` : The type of the component to be set on the implementing object. This type represents
/// the final form of the component as it should be stored or represented in the object.
///
/// # Examples
///
/// Using `option_assign` to set a component on an `Option` :
///
/// ```rust
/// use component_model_types :: { Assign, OptionExt }; // use crate `component_model` instead of crate `component_model_types` unless you need to use crate `component_model_types` directly
///
/// struct MyStruct
/// {
/// name: String,
/// }
///
/// impl< IntoT: Into< MyStruct > > Assign< MyStruct, IntoT > for MyStruct
/// {
/// fn assign( &mut self, component: IntoT )
/// {
/// self.name = component.into().name;
/// }
/// }
///
/// let mut opt_struct: Option< MyStruct > = None;
/// opt_struct.option_assign( MyStruct { name: "New Name".to_string() } );
/// assert_eq!( opt_struct.unwrap().name, "New Name" );
/// ```
/// The `AssignWithType` trait provides a mechanism to set a component on an object,
/// utilizing the type information explicitly. This trait extends the functionality of `Assign`
/// by allowing implementers to specify the component's type at the method call site,
/// enhancing expressiveness in code that manipulates object states.
///
/// # Type Parameters
///
/// - `T` : The type of the component to be set on the implementing object. This specifies
/// the exact type expected by the object as its component.
/// - `IntoT` : A type that can be converted into `T`, providing flexibility in the types of values
/// that can be used to set the component.
///
/// # Examples
///
/// Implementing `AssignWithType` to set a username on a struct :
///
/// ```rust
/// use component_model_types :: { Assign, AssignWithType }; // use crate `component_model` instead of crate `component_model_types` unless you need to use crate `component_model_types` directly
///
/// struct UserProfile
/// {
/// username: String,
/// }
///
/// impl< IntoT: Into< String > > Assign< String, IntoT > for UserProfile
/// {
/// fn assign( &mut self, component: IntoT )
/// {
/// self.username = component.into();
/// }
/// }
///
/// let mut user_profile = UserProfile { username: String ::new() };
/// user_profile.assign_with_type :: < String, _ >("john_doe");
///
/// assert_eq!( user_profile.username, "john_doe" );
/// ```