shors 0.13.0

Transport layer for cartridge + tarantool-module projects.
Documentation
pub mod retry {
    use crate::tarantool::fiber::sleep;
    use std::time::Duration;
    use thiserror::Error;

    #[derive(Debug, Error)]
    #[error("Retry error. Error: {source}, delay: {total_delay:?}, tries: {tries}")]
    pub struct RetryError<E> {
        pub source: E,
        total_delay: Duration,
        tries: u64,
    }

    #[allow(dead_code)]
    pub enum OpResult<T, E> {
        Ok(T),
        Retry(E),
        Stop(E),
    }

    impl<T, E> From<std::result::Result<T, E>> for OpResult<T, E> {
        fn from(r: std::result::Result<T, E>) -> OpResult<T, E> {
            match r {
                Ok(r) => OpResult::Ok(r),
                Err(e) => OpResult::Retry(e),
            }
        }
    }

    pub fn retry<I, O, T, E, R>(mut iterable: I, mut op: O) -> Result<T, RetryError<E>>
    where
        I: Iterator<Item = Duration>,
        R: Into<OpResult<T, E>>,
        O: FnMut() -> R,
    {
        let mut total_delay = Duration::default();
        let mut tries = 1;

        loop {
            let rv = op().into();
            match rv {
                OpResult::Ok(value) => return Ok(value),
                OpResult::Retry(err) => {
                    if let Some(delay) = iterable.next() {
                        sleep(delay);
                        total_delay += delay;
                        tries += 1;
                    } else {
                        return Err(RetryError {
                            source: err,
                            total_delay,
                            tries,
                        });
                    }
                }
                OpResult::Stop(err) => {
                    return Err(RetryError {
                        source: err,
                        total_delay,
                        tries,
                    })
                }
            };
        }
    }

    #[derive(Debug, Clone, Copy)]
    pub struct Fibonacci {
        curr: u64,
        next: u64,
    }

    impl Fibonacci {
        pub fn from_millis(millis: u64) -> Fibonacci {
            Fibonacci {
                curr: millis,
                next: millis,
            }
        }
    }

    impl Iterator for Fibonacci {
        type Item = Duration;

        fn next(&mut self) -> Option<Duration> {
            if let Some(next_next) = self.curr.checked_add(self.next) {
                self.curr = self.next;
                self.next = next_next;
            } else {
                self.curr = self.next;
                self.next = u64::MAX;
            }

            let duration = Duration::from_millis(self.curr);
            Some(duration)
        }
    }

    #[test]
    fn fibonacci() {
        let mut iter = Fibonacci::from_millis(10);
        assert_eq!(iter.next(), Some(Duration::from_millis(10)));
        assert_eq!(iter.next(), Some(Duration::from_millis(20)));
        assert_eq!(iter.next(), Some(Duration::from_millis(30)));
        assert_eq!(iter.next(), Some(Duration::from_millis(50)));
        assert_eq!(iter.next(), Some(Duration::from_millis(80)));
    }
}