#reflection #meta #introspection #type #metaclass

nightly type-info

Meta type information and type reflection at compile-time and runtime

3 unstable releases

Uses old Rust 2015

0.2.1 Apr 29, 2018
0.2.0 Apr 29, 2018
0.1.0 Apr 26, 2018

#1852 in Data structures


Used in 2 crates (via type-info-derive)

MIT license

14KB
170 lines

type-info docs

An implementation of detailed type information and reflection.

This library provides simple access to type information at runtime, as well as the ability to manipulate data whose type is not statically known.

See the API documentation for more information.


lib.rs:

An implementation of detailed type information and reflection.

This library provides simple access to type information at runtime, as well as the ability to manipulate data whose type is not statically known.

Type information

By deriving the TypeInfo trait, you get access to type information about the type at runtime.

#![feature(const_type_id)]

extern crate type_info;
#[macro_use]
extern crate type_info_derive;

use type_info::TypeInfo;

#[derive(TypeInfo)]
struct Person {
    name: String,
    age: u32,
}

fn main() {
    let ty = Person::TYPE;

    assert_eq!("Person", ty.ident);
    assert_eq!(vec!["name", "age"], ty.fields().iter().map(|f| f.ident.unwrap()).collect::<Vec<_>>());
}

Static dispatch

This example shows how to use the main TypeInfo trait with generic parameters (i.e. not trait objects):

#
#
// Person is defined like in the above example...

// A function that can take any type that has a field called "name" of type String.
fn add_smith_to_name<A>(anything: &mut A) where A: type_info::TypeInfo {
    let name = anything.field_mut::<String>(type_info::FieldId::Named("name")).unwrap();
    name.push_str(" Smith");
}

fn main() {
    let mut person = Person {
        name: "Lisa".to_owned(),
        age: 23,
    };

    add_smith_to_name(&mut person);

    assert_eq!("Lisa Smith", person.name.as_str());
}

Dynamic dispatch

This example shows how to use the DynamicTypeInfo trait when you don't want to introduce a type parameter to specialize a function, but instead prefer to use a trait object:

#
#
// Person is defined like in the above example...

// A function that can take any type that has a field called "name" of type String.
fn add_smith_to_name(anything: &mut type_info::DynamicTypeInfo) {
    let field = anything.field_any_mut(type_info::FieldId::Named("name")).unwrap();
    let name = field.downcast_mut::<String>().unwrap();
    name.push_str(" Smith");
}

fn main() {
    let mut person = Person {
        name: "Lisa".to_owned(),
        age: 23,
    };

    add_smith_to_name(&mut person);

    assert_eq!("Lisa Smith", person.name.as_str());
}

No runtime deps