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
/*!
Run-time type information trait. Use crate [`rtti-derive`](https://crates.io/crates/rtti-derive) to implement.

To include RTTI, use:

```
#[macro_use]
extern crate rtti_derive;
extern crate rtti;
use rtti::RTTI;
# fn main() {}
```

You can then implement `rtti()` for a custom type:

```
# #[macro_use]
# extern crate rtti_derive;
# extern crate rtti;
# use rtti::RTTI;
#
#[derive(RTTI)]
struct Simple {
    x: u32,
    pub y: ::std::sync::Arc<u32>,
    pub(crate) z: Vec<f64>
}

fn main() {
    println!("{:?}", Simple::ctti());
}
```

You can ignore fields or add hints using the ignore and hint attributes:

```
# #[macro_use]
# extern crate rtti_derive;
# extern crate rtti;
# use rtti::RTTI;
#
struct UnsupportedForeignType ();

#[derive(RTTI)]
struct Attributed {
    #[rtti(hint = "foo")]
    #[rtti(hint = "bar")]
    pub foobard: ::std::sync::Arc<u32>,
    #[rtti(ignore)]
    #[rtti(hint = "sets type to Type::Ignored")]
    ignored: UnsupportedForeignType,
}

fn main() {
    println!("{:?}", Attributed::ctti());
}
```

When implementing RTTI for a generic type, make sure generic parameters implement RTTI:

```
# #[macro_use]
# extern crate rtti_derive;
# extern crate rtti;
# use rtti::RTTI;
#[derive(RTTI)]
struct Generic<T> where T: RTTI {
    test: T,
    stuff: i32,
}

fn main() {
    println!("{:?}", Generic::<u64>::ctti());
}
```
*/
#[macro_use]
mod macros;
mod types;
pub use types::*;

/// Provides run-time type information.
pub trait RTTI {
    /// Returns a Type enum describing the type.
    fn ctti() -> Type;
    /// Returns a Type enum describing the type of the instance.
    fn rtti(self: &Self) -> Type {
        Self::ctti()
    }
}

#[doc(hidden)]
pub struct Ignored ();

impl RTTI for Ignored {
    fn ctti() -> Type {
        Type::Ignored
    }
}

// implement built in types
mod wrapper {
    impl_prim!(usize, usize);
    impl_prim!(isize, isize);
    impl_prim!(u8, u8);
    impl_prim!(i8, i8);
    impl_prim!(u16, u16);
    impl_prim!(i16, i16);
    impl_prim!(u32, u32);
    impl_prim!(i32, i32);
    impl_prim!(u64, u64);
    impl_prim!(i64, i64);
    impl_prim!(f32, f32);
    impl_prim!(f64, f64);
    impl_prim!(char, char);
    impl_prim!(bool, bool);
    impl_opaque!(std::rc::Rc, Rc);
    impl_opaque!(std::cell::Cell, Cell);
    impl_opaque!(std::cell::RefCell, RefCell);
    impl_opaque!(std::cell::UnsafeCell, UnsafeCell);
    impl_opaque!(std::boxed::Box, Box);
    impl_opaque!(std::sync::Arc, Arc);
    impl_opaque!(std::sync::Mutex, Mutex);
    impl_opaque!(std::sync::RwLock, RwLock);
    impl_opaque!(std::sync::Weak, Weak);
    impl_opaque!(std::vec::Vec, Vec);
    impl_opaque!(std::collections::VecDeque, VecDeque);
    impl_opaque!(std::collections::LinkedList, LinkedList);
    impl_opaque!(std::collections::BTreeSet, BTreeSet);
    impl_opaque!(std::collections::BinaryHeap, BinaryHeap);
    impl_opaque!(std::marker::PhantomData, PhantomData);
}