1 | #[macro_use ] |
2 | extern crate lazy_static; |
3 | use std::collections::HashMap; |
4 | |
5 | lazy_static! { |
6 | /// Documentation! |
7 | pub static ref NUMBER: u32 = times_two(3); |
8 | |
9 | static ref ARRAY_BOXES: [Box<u32>; 3] = [Box::new(1), Box::new(2), Box::new(3)]; |
10 | |
11 | /// More documentation! |
12 | #[allow (unused_variables)] |
13 | #[derive(Copy, Clone, Debug)] |
14 | pub static ref STRING: String = "hello" .to_string(); |
15 | |
16 | static ref HASHMAP: HashMap<u32, &'static str> = { |
17 | let mut m = HashMap::new(); |
18 | m.insert(0, "abc" ); |
19 | m.insert(1, "def" ); |
20 | m.insert(2, "ghi" ); |
21 | m |
22 | }; |
23 | |
24 | // This should not compile if the unsafe is removed. |
25 | static ref UNSAFE: u32 = unsafe { |
26 | std::mem::transmute::<i32, u32>(-1) |
27 | }; |
28 | } |
29 | |
30 | lazy_static! { |
31 | static ref S1: &'static str = "a" ; |
32 | static ref S2: &'static str = "b" ; |
33 | } |
34 | lazy_static! { |
35 | static ref S3: String = [*S1, *S2].join("" ); |
36 | } |
37 | |
38 | #[test] |
39 | fn s3() { |
40 | assert_eq!(&*S3, "ab" ); |
41 | } |
42 | |
43 | fn times_two(n: u32) -> u32 { |
44 | n * 2 |
45 | } |
46 | |
47 | #[test] |
48 | fn test_basic() { |
49 | assert_eq!(&**STRING, "hello" ); |
50 | assert_eq!(*NUMBER, 6); |
51 | assert!(HASHMAP.get(&1).is_some()); |
52 | assert!(HASHMAP.get(&3).is_none()); |
53 | assert_eq!(&*ARRAY_BOXES, &[Box::new(1), Box::new(2), Box::new(3)]); |
54 | assert_eq!(*UNSAFE, std::u32::MAX); |
55 | } |
56 | |
57 | #[test] |
58 | fn test_repeat() { |
59 | assert_eq!(*NUMBER, 6); |
60 | assert_eq!(*NUMBER, 6); |
61 | assert_eq!(*NUMBER, 6); |
62 | } |
63 | |
64 | #[test] |
65 | fn test_meta() { |
66 | // this would not compile if STRING were not marked #[derive(Copy, Clone)] |
67 | let copy_of_string = STRING; |
68 | // just to make sure it was copied |
69 | assert!(&STRING as *const _ != ©_of_string as *const _); |
70 | |
71 | // this would not compile if STRING were not marked #[derive(Debug)] |
72 | assert_eq!(format!("{:?}" , STRING), "STRING { __private_field: () }" .to_string()); |
73 | } |
74 | |
75 | mod visibility { |
76 | lazy_static! { |
77 | pub static ref FOO: Box<u32> = Box::new(0); |
78 | static ref BAR: Box<u32> = Box::new(98); |
79 | } |
80 | |
81 | pub mod inner { |
82 | lazy_static! { |
83 | pub(in visibility) static ref BAZ: Box<u32> = Box::new(42); |
84 | pub(crate) static ref BAG: Box<u32> = Box::new(37); |
85 | } |
86 | } |
87 | |
88 | #[test] |
89 | fn sub_test() { |
90 | assert_eq!(**FOO, 0); |
91 | assert_eq!(**BAR, 98); |
92 | assert_eq!(**inner::BAZ, 42); |
93 | assert_eq!(**inner::BAG, 37); |
94 | } |
95 | } |
96 | |
97 | #[test] |
98 | fn test_visibility() { |
99 | assert_eq!(*visibility::FOO, Box::new(0)); |
100 | assert_eq!(*visibility::inner::BAG, Box::new(37)); |
101 | } |
102 | |
103 | // This should not cause a warning about a missing Copy implementation |
104 | lazy_static! { |
105 | pub static ref VAR: i32 = { 0 }; |
106 | } |
107 | |
108 | #[derive(Copy, Clone, Debug, PartialEq)] |
109 | struct X; |
110 | struct Once(X); |
111 | const ONCE_INIT: Once = Once(X); |
112 | static DATA: X = X; |
113 | static ONCE: X = X; |
114 | fn require_sync() -> X { X } |
115 | fn transmute() -> X { X } |
116 | fn __static_ref_initialize() -> X { X } |
117 | fn test(_: Vec<X>) -> X { X } |
118 | |
119 | // All these names should not be shadowed |
120 | lazy_static! { |
121 | static ref ITEM_NAME_TEST: X = { |
122 | test(vec![X, Once(X).0, ONCE_INIT.0, DATA, ONCE, |
123 | require_sync(), transmute(), |
124 | // Except this, which will sadly be shadowed by internals: |
125 | // __static_ref_initialize() |
126 | ]) |
127 | }; |
128 | } |
129 | |
130 | #[test] |
131 | fn item_name_shadowing() { |
132 | assert_eq!(*ITEM_NAME_TEST, X); |
133 | } |
134 | |
135 | use std::sync::atomic::AtomicBool; |
136 | #[allow (deprecated)] |
137 | use std::sync::atomic::ATOMIC_BOOL_INIT; |
138 | use std::sync::atomic::Ordering::SeqCst; |
139 | |
140 | #[allow (deprecated)] |
141 | static PRE_INIT_FLAG: AtomicBool = ATOMIC_BOOL_INIT; |
142 | |
143 | lazy_static! { |
144 | static ref PRE_INIT: () = { |
145 | PRE_INIT_FLAG.store(true, SeqCst); |
146 | () |
147 | }; |
148 | } |
149 | |
150 | #[test] |
151 | fn pre_init() { |
152 | assert_eq!(PRE_INIT_FLAG.load(SeqCst), false); |
153 | lazy_static::initialize(&PRE_INIT); |
154 | assert_eq!(PRE_INIT_FLAG.load(SeqCst), true); |
155 | } |
156 | |
157 | lazy_static! { |
158 | static ref LIFETIME_NAME: for<'a> fn(&'a u8) = { fn f(_: &u8) {} f }; |
159 | } |
160 | |
161 | #[test] |
162 | fn lifetime_name() { |
163 | let _ = LIFETIME_NAME; |
164 | } |
165 | |