1use std::{
2 collections::hash_map::DefaultHasher,
3 hash::{Hash, Hasher},
4 thread,
5 time::Duration,
6};
7
8pub fn hash(obj: impl ToString + Hash) -> u64 {
9 let mut hasher = DefaultHasher::new();
10 obj.hash(&mut hasher);
11 hasher.finish()
12}
13
14pub fn sleep(duration: impl Into<f32>) {
15 let duration = duration.into();
16 assert!(duration >= 0.0);
17
18 if duration == 0.0 {
19 return;
20 }
21
22 #[allow(clippy::cast_possible_truncation)]
23 #[allow(clippy::cast_sign_loss)]
24 thread::sleep(Duration::from_micros((duration * 1_000_000.0) as _));
25}
26
27pub trait Toggle {
28 fn toggle(&mut self) -> bool;
29}
30
31impl Toggle for bool {
33 fn toggle(&mut self) -> bool {
34 *self = !*self;
35 !*self
36 }
37}
38
39#[cfg(test)]
40mod test {
41
42 use crate::{Toggle, hash, passed::Passed, sleep};
43
44 #[test]
45 fn toggle() {
46 let mut val = true;
47
48 for _ in 0..10 {
49 let prev = val;
50 assert_eq!(val.toggle(), prev);
51 assert_eq!(val, !prev);
52 }
53 }
54
55 #[test]
56 fn misc() {
57 assert_eq!(397663693774528972, hash(54325));
58 assert_eq!(13713634450856707654, hash(8657865));
59 assert_eq!(5949921715258702887, hash(87));
60 }
61
62 #[test]
63 fn test_sleep() {
64 let mut pass = Passed::default();
65
66 sleep(0.2);
67 let passed = pass.passed();
68 assert!(passed >= 200);
69 assert!(passed < 220);
70 }
71}