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
#![feature(core_intrinsics)]
extern crate regex;
use regex::{Captures, Regex};
use std::hash::{Hash, Hasher, SipHasher};
use std::intrinsics;
use std::mem::{align_of, size_of};
pub fn layout_id<T>() -> u64 {
let mut s = SipHasher::new();
get_type_name(unsafe { intrinsics::type_name::<T>() }).hash(&mut s);
align_of::<T>().hash(&mut s);
size_of::<T>().hash(&mut s);
s.finish()
}
fn get_type_name(name: &str) -> String {
let inner = Regex::new(r#"<(.*)>"#).unwrap();
let last_name = Regex::new(r#"[::]?([^:]*)$"#).unwrap();
let replaced_children = inner.replace_all(&name, |caps: &Captures| {
format!("<{}>", get_type_name(&caps.at(1).unwrap()))
});
let caps = last_name.captures(&replaced_children).unwrap();
String::from(caps.at(1).unwrap())
}
#[test]
fn test_get_type_name() {
assert_eq!(&get_type_name("persistent_hashmap::HashmapEntry<user::User>"),
"HashmapEntry<User>");
assert_eq!(&get_type_name("persistent_hashmap::HashmapEntry<meus_iot::user::User>"),
"HashmapEntry<User>");
assert_eq!(&get_type_name("persistent_hashmap::HashmapEntry<meus_iot::user::User<test::Type>>"),
"HashmapEntry<User<Type>>");
assert_eq!(&get_type_name("HashmapEntry<User>"),
"HashmapEntry<User>");
}