FieldsInspect

Trait FieldsInspect 

Source
pub trait FieldsInspect {
    // Required methods
    fn struct_name(&self) -> &'static str;
    fn fields_count(&self) -> u32;
    fn field_name(&self, n: u32) -> &'static str;
    fn field(&self, n: u32) -> &dyn Any;
    fn field_mut(&mut self, n: u32) -> &mut dyn Any;
}
Expand description

A trait that allows iterating over over struct’s fields, getting their name and a mutable/shared reference to them.

You need to derive this trait (actually, it the derive creates an impl for a hidden trait this trait has a blanket implementation to).

§Examples

Printing the values of all field whose name starts with “a” and are strings:

use fields_iter::{FieldsInspect, FieldsIter};

fn print_starts_with_a(v: &dyn FieldsInspect) {
    for (name, value) in FieldsIter::new(v) {
        if !name.starts_with('a') { continue };
        let Some(value) = value.downcast_ref::<String>() else { continue };
        println!("{name}={value}");
    }
}

Adding one to the field add_here:

use fields_iter::{FieldsInspect, FieldsIterMut};

let v: &mut dyn FieldsInspect;
let field = FieldsIterMut::new(v)
    .find(|&(name, _)| name == "add_here")
    .expect("no `add_here` field")
    .1
    .downcast_mut::<i32>()
    .expect("field `add_here` is not of type `i32`");
*field += 1;

Required Methods§

Source

fn struct_name(&self) -> &'static str

The struct name.

This takes &self to make FieldsIter object safe.

Source

fn fields_count(&self) -> u32

The numbers of fields.

This allows you to iterate over the fields without allocating a Box and in no_std mode.

This takes &self to make FieldsIter object safe.

§Example
#[derive(FieldsInspect)]
struct HasFieldsInspect {
    a: i32,
    b: String,
}

let v = HasFieldsInspect { a: 0, b: String::new() };
assert_eq!(v.fields_count(), 2);

This takes &self to make FieldsIter object safe.

Source

fn field_name(&self, n: u32) -> &'static str

The name of the nth field.

Named fields return their name; tuple fields return their index (e.g. “1”, “2”).

This allows you to iterate over the fields without allocating a Box and in no_std mode.

This takes &self to make FieldsIter object safe.

§Example
#[derive(FieldsInspect)]
struct HasFieldsInspect {
    a: i32,
    b: String,
}

let v = HasFieldsInspect { a: 0, b: String::new() };
assert_eq!(v.field_name(0), "a");
assert_eq!(v.field_name(1), "b");
§Panics

This panics if given an out of bounds field index.

Source

fn field(&self, n: u32) -> &dyn Any

The value of the nth field.

This allows you to iterate over the fields without allocating a Box and in no_std mode.

§Example
#[derive(FieldsInspect)]
struct HasFieldsInspect {
    a: i32,
    b: String,
}

let v = HasFieldsInspect { a: 0, b: String::new() };
assert!(std::ptr::eq(v.field(0), &v.a));
assert!(std::ptr::eq(v.field(1), &v.b));
§Panics

This panics if given an out of bounds field index.

Source

fn field_mut(&mut self, n: u32) -> &mut dyn Any

The value of the nth field.

This allows you to iterate over the fields without allocating a Box and in no_std mode.

§Example
#[derive(FieldsInspect)]
struct HasFieldsInspect {
    a: i32,
    b: String,
}

let mut v = HasFieldsInspect { a: 0, b: String::new() };
*v.field_mut(0).downcast_mut::<i32>().unwrap() += 5;
assert_eq!(v.a, 5);
§Panics

This panics if given an out of bounds field index.

Implementors§

Source§

impl<T: ?Sized + FieldsInspectImpl> FieldsInspect for T