Introspection trait

This commit is contained in:
Ulrich Mohr 2024-02-08 18:02:47 +01:00
parent 7ba3f23add
commit 8e8b3f3da4

View File

@ -0,0 +1,63 @@
/// A trait to allow objects to be queried for some of their inner attributes at runtime.
///
pub trait Introspection {
/// Executes a function/closure on all members of the implementing struct.
///
/// The parameters for the closure a reference to the member as well as the name of the member.
///
/// To keep the trait object safe, we need to pass the closure as a reference. Otherwise,
/// the trait can not be used as a `dyn` reference, because the function becomes generic.
/// (Either using `impl FnMut` not `where F: FnMut` will be treated as generic making the
/// trait not object safe).
/// Additionally, the closure is typed as `FnMut`, to allow the closure to capture mutably.
///
///
/// # Examples
///
/// ```rust
/// use fsrc::introspection::Introspection;
///
/// struct Empty {}
///
/// impl Empty {
/// fn getRandomNumber(&self) -> u8 {
/// return 4 // chosen by fair dice roll.
/// // guaranteed to be random.
/// }
/// }
///
/// fn parsing_something(something: &dyn Introspection) {
/// let mut a = 0;
/// something.for_each_member(&mut |x, _| {
/// if let Some( empty) = x.downcast_ref::<Empty>() {
/// a = empty.getRandomNumber();
/// }
/// });
/// }
/// ````
///
fn for_each_member(&self, f: &mut dyn FnMut(&dyn core::any::Any, &str) -> ());
/// Same as [for_each_member](Introspection::for_each_member), only with a return value for the closure.
///
/// # Examples
///
/// The return value allows using `x.downcast_ref()?` or similar constructs in the closure like in:
///
/// ```rust
/// use fsrc::introspection::Introspection;
///
/// struct Empty {}
///
/// fn do_something(_: &Empty) {}
///
/// fn parsing_something(something: &dyn Introspection) {
/// something.for_each_member_return(&mut |x, _| {
/// do_something(x.downcast_ref()?);
/// None
/// });
/// }
/// ```
///
fn for_each_member_return(&self, f: &mut dyn FnMut(&dyn core::any::Any, &str) -> Option<()>);
}