File: namegen.rs

package info (click to toggle)
rust-interprocess 2.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,016 kB
  • sloc: makefile: 2
file content (57 lines) | stat: -rw-r--r-- 1,783 bytes parent folder | download
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
54
55
56
57
use {
    super::Xorshift32,
    crate::local_socket::{GenericFilePath, GenericNamespaced, Name, ToFsName, ToNsName},
    std::{io, sync::Arc},
};

#[derive(Copy, Clone, Debug)]
pub struct NameGen<T: ?Sized, F: FnMut(u32) -> NameResult<T>> {
    rng: Xorshift32,
    name_fn: F,
}
impl<T: ?Sized, F: FnMut(u32) -> NameResult<T>> NameGen<T, F> {
    pub fn new(id: &str, name_fn: F) -> Self { Self { rng: Xorshift32::from_id(id), name_fn } }
}
impl<T: ?Sized, F: FnMut(u32) -> NameResult<T>> Iterator for NameGen<T, F> {
    type Item = NameResult<T>;
    fn next(&mut self) -> Option<Self::Item> { Some((self.name_fn)(self.rng.next())) }
}

pub type NameResult<T> = io::Result<Arc<T>>;

pub fn namegen_local_socket(
    id: &str,
    path: bool,
) -> NameGen<Name<'static>, impl FnMut(u32) -> io::Result<Arc<Name<'static>>>> {
    NameGen::new(id, move |rn| if path { next_fs(rn) } else { next_ns(rn) }.map(Arc::new))
}

fn next_fs(rn: u32) -> io::Result<Name<'static>> {
    if cfg!(windows) {
        windows_path(rn)
    } else if cfg!(unix) {
        unix_path(rn)
    } else {
        unreachable!()
    }
    .to_fs_name::<GenericFilePath>()
}
fn next_ns(rn: u32) -> io::Result<Name<'static>> {
    format!("@interprocess-test-{:08x}", rn).to_ns_name::<GenericNamespaced>()
}

pub fn namegen_named_pipe(id: &str) -> NameGen<str, impl FnMut(u32) -> NameResult<str>> {
    NameGen::new(id, move |rn| Ok(windows_path(rn).into()))
}

fn windows_path(rn: u32) -> String { format!(r"\\.\pipe\interprocess-test-{rn:08x}") }
fn unix_path(rn: u32) -> String {
    let tmpdir = std::env::var("TMPDIR").ok();
    format!("{}/interprocess-test-{rn:08x}.sock", tmpdir.as_deref().unwrap_or("/tmp"))
}

macro_rules! make_id {
    () => {
        concat!(file!(), line!(), column!())
    };
}