1#[allow(unused)]
2macro_rules! cstr {
3 ($($bytes:tt)*) => {
4 CStr::from_bytes_with_nul($($bytes)*).expect("CStr with null")
5 };
6}
7
8pub(crate) fn path_to_cstring(
9 path: impl AsRef<std::path::Path>,
10) -> crate::Result<std::ffi::CString> {
11 let s = path.as_ref().as_os_str().to_string_lossy().to_string();
12 Ok(std::ffi::CString::new(s)?)
13}
14
15pub fn join_paths<I>(files: I) -> String
17where
18 I: IntoIterator,
19 I::Item: AsRef<str>,
20{
21 const SEP: char = if cfg!(windows) { ';' } else { ':' };
22 let mut buf = String::new();
23 let mut iter = files.into_iter().peekable();
24 while let Some(n) = iter.next() {
25 buf.push_str(n.as_ref());
26 if iter.peek().is_some() {
27 buf.push(SEP);
28 }
29 }
30 buf
31}
32
33pub fn random_string(len: usize) -> String {
35 use std::collections::hash_map::RandomState;
36 use std::hash::{BuildHasher, Hasher};
37
38 let mut seed = RandomState::new().build_hasher().finish();
39 let next = || {
40 seed = seed.wrapping_mul(1103515245).wrapping_add(12345);
41 ((seed % 26) + 97) as u8 as char
42 };
43 std::iter::repeat_with(next).take(len).collect()
44}