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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
//!
//! Mechanism for reflection.
//!
use super::*;
/// Define a private namespace for all its items.
mod private
{
use super::*;
/// Provides a reflection of an instance that implements the `Instance` trait.
///
/// This function is required to distinguish between instances of a type and references to an instance
/// in contexts where `self` is used. Without this function, associated trait functions would not differentiate
/// between `i32` and `&i32`, treating both identically.
///
/// # Arguments
///
/// * `src` - A reference to an instance that implements the `Instance` trait.
///
/// # Returns
///
/// Returns an entity descriptor that implements the `Entity` trait, providing
/// runtime reflection capabilities for the given instance.
pub fn reflect( src : &impl Instance ) -> impl Entity
{
src._reflect()
}
///
/// Trait indicating that an entity is a container.
///
/// Implementors of `IsContainer` are considered to be container types,
/// which can hold zero or more elements. This trait is typically used in
/// conjunction with reflection mechanisms to dynamically inspect, access,
/// or modify the contents of a container at runtime.
pub trait IsContainer : Instance
{
}
///
/// Trait indicating that an entity is a scalar value.
///
/// Implementors of `IsScalar` are considered to be scalar types,
/// representing single, indivisible values as opposed to composite entities
/// like arrays or structs. This distinction can be useful in reflection-based
/// APIs or generic programming to treat scalar values differently from containers
/// or other complex types.
pub trait IsScalar : Instance
{
}
///
/// Represents a trait for enabling runtime reflection of entities.
///
/// This trait is designed to equip implementing structs with the ability to introspect
/// their properties, type names, and any contained elements. It facilitates runtime inspection
/// and manipulation of entities in a dynamic manner.
///
pub trait Instance
{
/// The entity descriptor associated with this instance.
type Entity : Entity;
/// Returns a descriptor for the current instance.
///
/// Don't use manually.
fn _reflect( &self ) -> Self::Entity
{
Self::Reflect()
}
/// Returns a descriptor for the type of the instance.
#[ allow( non_snake_case ) ]
fn Reflect() -> Self::Entity;
}
impl< T > Instance for T
where
EntityDescriptor< T > : Entity,
T : InstanceMarker,
{
type Entity = EntityDescriptor::< Self >;
#[ inline( always ) ]
fn Reflect() -> Self::Entity
{
EntityDescriptor::< Self >::new()
}
}
///
/// The `Entity` trait defines a common interface for entities within a system, enabling
/// runtime reflection, inspection, and manipulation of their properties and elements. It
/// serves as a foundational component for dynamic entity handling, where entities can
/// represent data structures, components, or other logical units with introspectable
/// and manipulable state.
///
/// ## Usage
///
/// Implementing the `Entity` trait allows a type to be integrated into systems that require
/// dynamic type inspection and manipulation, such as serialization frameworks, object-relational
/// mapping (ORM) systems, or generic containers and algorithms that operate on heterogeneous
/// entity collections.
///
/// ## Key Concepts
///
/// - **Containment**: Entities can act as containers for other entities, enabling hierarchical
/// or composite data models.
///
/// - **Ordering**: The trait distinguishes between ordered and unordered entities, affecting
/// how their elements are iterated over or accessed.
///
/// - **Reflection**: Through type metadata and element access methods, entities support
/// reflection, allowing programmatic querying and manipulation of their structure and state.
///
/// ## Implementing `Entity`
///
/// To implement the `Entity` trait, a type must provide implementations for all non-default
/// methods (`type_name`, `type_id`). The default method implementations assume non-container
/// entities with no elements and predictable ordering. Implementers should override these
/// defaults as appropriate to accurately reflect their specific semantics and behavior.
///
/// ## Example
///
/// ```
/// # use reflect_tools::reflect::Entity;
///
/// #[ derive(Debug)]
/// struct MyEntity
/// {
/// // Entity fields
/// }
///
/// impl Entity for MyEntity
/// {
///
/// #[ inline ]
/// fn type_name( &self ) -> &'static str
/// {
/// "MyEntity"
/// }
///
/// #[ inline ]
/// fn type_id(&self) -> core::any::TypeId
/// {
/// core::any::TypeId::of::< MyEntity >()
/// }
///
/// // Additional method implementations as necessary...
/// }
/// ```
///
/// This trait is designed to be flexible and extensible, accommodating a wide variety of entity
/// types and use cases. Implementers are encouraged to leverage Rust's type system and trait
/// mechanisms to provide rich, dynamic behavior in a type-safe manner.
///
pub trait Entity : core::fmt::Debug
{
/// Determines if the entity acts as a container for other entities.
///
/// # Returns
///
/// Returns `true` if the entity can contain other entities (like a struct, vector, etc.),
/// otherwise `false`.
///
/// By default, this method returns `false`, assuming that the entity does not act as a container.
#[ inline( always ) ]
fn is_container( &self ) -> bool
{
false
}
/// Determines if the elements of the container are maintained in a specific order.
///
/// This method indicates whether the container preserves a specific order of its elements.
/// The concept of "order" can refer to:
/// - **Sorted Order**: Where elements are arranged based on a sorting criterion, typically
/// through comparison operations.
/// - **Insertion Order**: Where elements retain the order in which they were added to the container.
///
/// It is important to distinguish this property in collections to understand how iteration over
/// the elements will proceed and what expectations can be held about the sequence of elements
/// when accessed.
///
/// # Returns
///
/// - `true` if the container maintains its elements in a predictable order. This is typically
/// true for data structures like arrays, slices, and vectors, where elements are accessed
/// sequentially or are sorted based on inherent or specified criteria.
/// - `false` for collections where the arrangement of elements does not follow a predictable
/// sequence from the perspective of an observer, such as sets and maps implemented via hashing.
/// In these structures, the order of elements is determined by their hash and internal state,
/// rather than the order of insertion or sorting.
///
/// By default, this method returns `true`, assuming that the entity behaves like an array, slice,
/// or vector, where the order of elements is consistent and predictable. Implementers should override
/// this behavior for collections where element order is not maintained or is irrelevant.
#[ inline( always ) ]
fn is_ordered( &self ) -> bool
{
true
}
/// Returns the number of elements contained in the entity.
///
/// # Returns
///
/// Returns the count of elements if the entity is a container, otherwise `0`.
///
/// This method is particularly useful for collections or composite entities.
/// By default, this method returns `0`, assuming the entity contains no elements.
#[ inline( always ) ]
fn len( &self ) -> usize
{
0
}
/// Retrieves the type name.
///
/// # Returns
///
/// Returns the type name of the implementing entity as a static string slice.
///
/// This method leverages Rust's `type_name` function to provide the name at runtime,
/// aiding in debugging and logging purposes.
fn type_name( &self ) -> &'static str;
/// Retrives the typ id.
fn type_id( &self ) -> core::any::TypeId;
/// Provides an iterator over the elements contained within the entity, if any.
///
/// # Returns
///
/// Returns a boxed iterator over `KeyVal` pairs representing the key-value mappings
/// of the entity's elements. For non-container entities, an empty iterator is returned.
///
/// This method is crucial for traversing composite entities or collections at runtime,
/// allowing for dynamic inspection and manipulation.
#[ inline( always ) ]
fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > >
{
Box::new( [].into_iter() )
}
/// Returns a descriptor for the type of the instance.
///
/// # Returns
///
/// Returns an entity descriptor that implements the `Entity` trait.
#[ inline( always ) ]
fn element( &self, i : usize ) -> KeyVal
{
debug_assert!( i < self.len() );
self.elements().skip( i ).next().unwrap()
}
}
///
/// Type descriptor
///
#[ derive( PartialEq, Default, Clone ) ]
pub struct EntityDescriptor< I : Instance >
{
_phantom : core::marker::PhantomData< I >,
}
impl< I : Instance > EntityDescriptor< I >
{
/// Constructor of the descriptor.
#[ inline( always ) ]
pub fn new() -> Self
{
let _phantom = core::marker::PhantomData::< I >;
Self { _phantom }
}
}
///
/// Dynamically sized collection descriptor
///
#[ derive( PartialEq, Default, Clone ) ]
pub struct CollectionDescriptor< I : Instance >
{
/// Container length.
pub len : usize,
_phantom : core::marker::PhantomData< I >,
}
impl< I : Instance > CollectionDescriptor< I >
{
/// Constructor of the descriptor of container type.
pub fn new( size : usize ) -> Self
{
let _phantom = core::marker::PhantomData::< I >;
Self
{
_phantom,
len : size,
}
}
}
///
/// Dynamically sized key-value collection descriptor
///
#[ derive( PartialEq, Default, Clone ) ]
pub struct KeyedCollectionDescriptor< I : Instance >
{
/// Container length.
pub len : usize,
/// Container keys.
pub keys : Vec< primitive::Primitive >,
_phantom : core::marker::PhantomData< I >,
}
impl< I : Instance > KeyedCollectionDescriptor< I >
{
/// Constructor of the descriptor of container type.
pub fn new( size : usize, keys : Vec< primitive::Primitive > ) -> Self
{
let _phantom = core::marker::PhantomData::< I >;
Self
{
_phantom,
len : size,
keys,
}
}
}
/// Auto-implement descriptor for this type.
trait InstanceMarker {}
impl< T > Entity for EntityDescriptor< T >
where
T : InstanceMarker + 'static,
{
#[ inline( always ) ]
fn type_name( &self ) -> &'static str
{
core::any::type_name::< T >()
}
#[ inline( always ) ]
fn type_id( &self ) -> core::any::TypeId
{
core::any::TypeId::of::< T >()
}
}
impl< T > core::fmt::Debug for EntityDescriptor< T >
where
T : Instance + 'static,
EntityDescriptor< T > : Entity,
{
fn fmt( &self, f: &mut core::fmt::Formatter< '_ > ) -> core::fmt::Result
{
f
.write_str( &format!( "{}#{:?}", Entity::type_name( self ), self.type_id() ) )
}
}
impl< T > core::fmt::Debug for CollectionDescriptor< T >
where
T : Instance + 'static,
CollectionDescriptor< T > : Entity,
{
fn fmt( &self, f: &mut core::fmt::Formatter< '_ > ) -> core::fmt::Result
{
f
.write_str( &format!( "{}#{:?}", Entity::type_name( self ), self.type_id() ) )
}
}
impl< T > core::fmt::Debug for KeyedCollectionDescriptor< T >
where
T : Instance + 'static,
KeyedCollectionDescriptor< T > : Entity,
{
fn fmt( &self, f: &mut core::fmt::Formatter< '_ > ) -> core::fmt::Result
{
f
.write_str( &format!( "{}#{:?}", Entity::type_name( self ), self.type_id() ) )
}
}
/// Represents a key-value pair where the key is a static string slice
/// and the value is a boxed entity that implements the `AnyEntity` trait.
///
/// This struct is typically used in the context of reflecting over the properties
/// or members of a container entity, allowing for dynamic access and inspection
/// of its contents.
///
// #[ derive( PartialEq, Debug ) ]
// #[ derive( Default ) ]
pub struct KeyVal
{
/// The key associated with the value in the key-value pair.
pub key : primitive::Primitive,
// pub key : &'static str,
/// The value associated with the key in the key-value pair.
pub val : Box< dyn Entity >,
}
impl Default for KeyVal
{
fn default() -> Self
{
Self
{
key : primitive::Primitive::default(),
val : Box::new( EntityDescriptor::< i8 >::new() ) as Box::< dyn Entity >,
}
}
}
impl core::fmt::Debug for KeyVal
{
fn fmt( &self, f: &mut core::fmt::Formatter< '_ > ) -> core::fmt::Result
{
f
.debug_struct( "KeyVal" )
.field( "key", &self.key )
.field( "val", &format_args!( "{:?}", &self.val ) )
.finish()
}
}
// qqq aaa: added comparison by val
impl PartialEq for KeyVal
{
fn eq( &self, other : &Self ) -> bool
{
let mut equal = self.key == other.key
&& self.val.type_id() == other.val.type_id()
&& self.val.type_name() == other.val.type_name()
&& self.val.len() == other.val.len();
if equal
{
for i in 0..self.val.len()
{
equal = equal && ( self.val.element( i ) == other.val.element( i ) )
}
}
equal
}
}
impl InstanceMarker for i8 {}
impl InstanceMarker for i16 {}
impl InstanceMarker for i32 {}
impl InstanceMarker for i64 {}
impl InstanceMarker for u8 {}
impl InstanceMarker for u16 {}
impl InstanceMarker for u32 {}
impl InstanceMarker for u64 {}
impl InstanceMarker for f32 {}
impl InstanceMarker for f64 {}
impl InstanceMarker for String {}
impl InstanceMarker for &'static str {}
impl< T > InstanceMarker for &T
where T : InstanceMarker
{}
impl IsScalar for i8 {}
impl IsScalar for i16 {}
impl IsScalar for i32 {}
impl IsScalar for i64 {}
impl IsScalar for u8 {}
impl IsScalar for u16 {}
impl IsScalar for u32 {}
impl IsScalar for u64 {}
impl IsScalar for f32 {}
impl IsScalar for f64 {}
impl IsScalar for String {}
impl IsScalar for &'static str {}
impl< T : Instance + 'static, const N : usize > IsContainer for [ T ; N ] {}
// qqq : aaa : added implementation for slice
impl< T : Instance > IsContainer for &'static [ T ] {}
// qqq : aaa : added implementation for Vec
impl< T : Instance + 'static > IsContainer for Vec< T > {}
// qqq : aaa : added implementation for HashMap
impl< K : IsScalar + Clone + 'static, V : Instance + 'static > IsContainer for std::collections::HashMap< K, V >
where primitive::Primitive : From< K > {}
// qqq : aaa : added implementation for HashSet
impl< V : Instance + 'static > IsContainer for std::collections::HashSet< V > {}
}
#[ doc( inline ) ]
#[ allow( unused_imports ) ]
pub use own::*;
/// Own namespace of the module.
#[ allow( unused_imports ) ]
pub mod own
{
use super::*;
#[ doc( inline ) ]
pub use orphan::*;
}
/// Orphan namespace of the module.
#[ allow( unused_imports ) ]
pub mod orphan
{
use super::*;
#[ doc( inline ) ]
pub use exposed::*;
#[ doc( inline ) ]
pub use private::
{
// reflect,
IsContainer,
IsScalar,
Instance,
// InstanceMarker,
Entity,
EntityDescriptor,
CollectionDescriptor,
KeyedCollectionDescriptor,
KeyVal,
};
}
/// Exposed namespace of the module.
#[ allow( unused_imports ) ]
pub mod exposed
{
use super::*;
#[ doc( inline ) ]
pub use prelude::*;
#[ doc( inline ) ]
pub use private::
{
reflect,
};
}
#[ doc( inline ) ]
#[ allow( unused_imports ) ]
pub use exposed::*;
/// Prelude to use essentials: `use my_module::prelude::*`.
#[ allow( unused_imports ) ]
pub mod prelude
{
use super::*;
}