ssh-rs 0.5.0

In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol
Documentation
use crate::{SshError, SshResult};
use std::time::{Duration, Instant};

#[cfg(not(target_arch = "wasm32"))]
const NANOS_PER_SEC: u64 = 1_000_000_000;

pub(crate) struct Timeout {
    instant: Instant,
    timeout: Option<Duration>,
    wait_tick: u64,
}

impl Timeout {
    pub fn new(timeout: Option<Duration>) -> Self {
        Timeout {
            instant: Instant::now(),
            timeout,
            wait_tick: 1,
        }
    }

    fn wait(&mut self) -> u64 {
        #[cfg(not(target_arch = "wasm32"))]
        {
            let sleep_time = Duration::from_nanos(self.wait_tick);
            std::thread::sleep(sleep_time);
            if self.wait_tick < NANOS_PER_SEC {
                self.wait_tick <<= 1;
            }

            if let Some(timemout) = self.timeout {
                let timeout_nanos = timemout.as_nanos();
                let used_nanos = self.instant.elapsed().as_nanos();

                self.wait_tick = {
                    if timeout_nanos > used_nanos
                        && timeout_nanos - used_nanos < self.wait_tick as u128
                    {
                        (timeout_nanos - used_nanos) as u64
                    } else {
                        self.wait_tick
                    }
                };
            }
        }
        self.wait_tick
    }

    pub fn till_next_tick(&mut self) -> SshResult<()> {
        if let Some(t) = self.timeout {
            if self.instant.elapsed() > t {
                tracing::error!("time out.");
                Err(SshError::TimeoutError)
            } else {
                self.wait();
                Ok(())
            }
        } else {
            self.wait();
            Ok(())
        }
    }

    pub fn renew(&mut self) {
        self.wait_tick = 1
    }
}