Skip to main content

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.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

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