namaste/
root.rs

1/*
2==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--
3
4Namaste
5
6Copyright (C) 2019, 2021-2025  Anonymous
7
8There are several releases over multiple years,
9they are listed as ranges, such as: "2021-2025".
10
11This program is free software: you can redistribute it and/or modify
12it under the terms of the GNU Lesser General Public License as published by
13the Free Software Foundation, either version 3 of the License, or
14(at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU Lesser General Public License for more details.
20
21You should have received a copy of the GNU Lesser General Public License
22along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
24::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
25*/
26
27//! # Root
28
29#![cfg(any(target_os="android", target_os="l4re", target_os="linux", windows))]
30#![doc(cfg(any(target_os="android", target_os="l4re", target_os="linux", windows)))]
31
32use {
33    core::{
34        fmt::Display,
35        time::Duration,
36    },
37    std::{
38        io::{self, Error, ErrorKind, Write},
39        time::Instant,
40    },
41    crate::{Namaste, Result},
42};
43
44pub use self::rw_namaste::*;
45
46macro_rules! sleep { () => {{
47    #[cfg(not(feature="tokio"))]
48    std::thread::sleep(SLEEP_DURATION);
49    #[cfg(feature="tokio")]
50    tokio::time::sleep(SLEEP_DURATION).await;
51}}}
52
53mod rw_namaste;
54
55/// # Sleep duration
56pub (crate) const SLEEP_DURATION: Duration = Duration::from_millis(sleep_duration!());
57
58/// # Makes new `Namaste`
59pub fn make<B>(id: B) -> Result<Namaste> where B: AsRef<[u8]> {
60    let result;
61
62    #[cfg(windows)] {
63        result = Namaste::make(id, crate::windows::Instance::One);
64    }
65
66    #[cfg(any(target_os="linux", target_os="l4re", target_os="android"))] {
67        result = Namaste::make(id, None);
68    }
69
70    result
71}
72
73macro_rules! make_wait { ($id: ident, $timeout: ident) => {{
74    let start = Instant::now();
75    loop {
76        match make(&$id) {
77            Ok(namaste) => return Ok(namaste),
78            Err(err) => match err.kind() {
79                ErrorKind::AddrInUse => {
80                    match Instant::now().checked_duration_since(start) {
81                        Some(duration) => if duration > $timeout {
82                            return Err(Error::new(ErrorKind::TimedOut, __!("Timed out")));
83                        },
84                        None => return Err(Error::new(ErrorKind::Other, __!("Invalid system time"))),
85                    };
86                    sleep!();
87                },
88                _ => return Err(err),
89            },
90        };
91    }
92}}}
93
94/// # Tries to make a `Namaste`...
95///
96/// If *the same ID is in use*, waits and tries again until timed out.
97#[cfg(not(feature="tokio"))]
98#[doc(cfg(not(feature="tokio")))]
99pub fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
100    make_wait!(id, timeout)
101}
102
103/// # Tries to make a `Namaste`...
104///
105/// If *the same ID is in use*, waits and tries again until timed out.
106#[cfg(feature="tokio")]
107#[doc(cfg(feature="tokio"))]
108pub async fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
109    make_wait!(id, timeout)
110}
111
112/// # Prints error
113pub (crate) fn print_err<S>(msg: S) where S: Display {
114    let msg = format!("{}\n", msg.to_string().trim());
115    if io::stderr().lock().write_all(msg.as_bytes()).is_err() {
116        eprintln!("{}", msg.trim());
117    }
118}