1use std::io;
2#[cfg(windows)]
3use std::mem;
4use std::path::Path;
5use std::time::{SystemTime, UNIX_EPOCH};
6
7pub(crate) const TRUE_AS_BYTE: u8 = 1;
8pub(crate) const FALSE_AS_BYTE: u8 = 0;
9
10#[cfg(windows)]
11use winapi::um::sysinfoapi::{GetSystemInfo, LPSYSTEM_INFO, SYSTEM_INFO};
12
13#[cfg(unix)]
15#[inline]
16pub(crate) fn get_vm_page_size() -> u32 {
17 unsafe { libc::sysconf(libc::_SC_PAGE_SIZE) as u32 }
18}
19
20#[cfg(windows)]
22#[inline]
23pub(crate) fn get_vm_page_size() -> u32 {
24 unsafe {
25 let mut info: SYSTEM_INFO = mem::zeroed();
26 GetSystemInfo(&mut info as LPSYSTEM_INFO);
27
28 info.dwPageSize as u32
29 }
30}
31
32pub(crate) fn get_current_timestamp() -> u64 {
34 let start = SystemTime::now();
35 let since_the_epoch = start
36 .duration_since(UNIX_EPOCH)
37 .expect("System time is poorly configured");
38 since_the_epoch.as_secs()
39}
40
41pub(crate) fn initialize_db_folder(store_path: &Path) -> io::Result<()> {
43 std::fs::create_dir_all(store_path)
44}
45
46pub(crate) fn slice_to_array<const N: usize>(data: &[u8]) -> io::Result<[u8; N]> {
48 data.try_into()
49 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
50}
51
52#[inline]
54pub(crate) fn byte_array_to_bool(data: &[u8]) -> bool {
55 data == [TRUE_AS_BYTE]
56}
57
58#[inline]
60pub(crate) fn bool_to_byte_array(value: bool) -> &'static [u8; 1] {
61 if value {
62 &[TRUE_AS_BYTE]
63 } else {
64 &[FALSE_AS_BYTE]
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use std::path::Path;
72
73 #[test]
74 fn get_vm_page_size_returns_page_size() {
75 assert!(get_vm_page_size() > 0)
76 }
77
78 #[test]
79 fn get_current_timestamp_gets_now() {
80 let some_time_in_october_2022 = 1666023836u64;
81 let now = get_current_timestamp();
82 assert!(
83 now > some_time_in_october_2022,
84 "got = {}, expected = {}",
85 now,
86 some_time_in_october_2022
87 );
88 }
89
90 #[test]
91 fn initialize_db_folder_creates_non_existing_db_folder() {
92 let store_path = Path::new("test_utils_db");
93 std::fs::remove_dir_all(store_path).unwrap_or(());
94 assert!(!Path::exists(store_path));
95
96 initialize_db_folder(store_path).expect("initializes db folder");
97
98 assert!(Path::exists(store_path));
99 std::fs::remove_dir_all(store_path).expect("removes the test_db_utils folder");
100 }
101
102 #[test]
103 fn slice_to_array_works() {
104 let data: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
105 let expected = [3u8, 4u8, 5u8, 6u8];
106 let got = slice_to_array::<4>(&data[3..7]).expect("extract 4 bytes starting at index 3");
107 assert_eq!(
108 &got, &expected,
109 "got = {:?}, expected = {:?}",
110 &got, &expected
111 );
112 }
113
114 #[test]
115 fn byte_array_to_bool_works() {
116 let test_data: [(&[u8], bool); 4] = [
117 (&[1][..], true),
118 (&[0][..], false),
119 (&[1, 1][..], false),
120 (&[0, 0, 0, 1, 0, 1][..], false),
121 ];
122
123 for (arr, expected) in test_data {
124 assert_eq!(byte_array_to_bool(arr), expected);
125 }
126 }
127}