three-commas-scraper 0.2.7

3commas scraper
use chrono::{DateTime, Utc};
use std::{
  borrow,
  cmp::Ordering,
  fmt,
  hash::{Hash, Hasher},
  ops::Deref,
  sync::Arc,
};

pub struct Cached<T: ?Sized> {
  data: Arc<T>,
  fetch_time: DateTime<Utc>,
}

impl<T> Cached<T> {
  pub fn new_at(data: T, fetch_time: DateTime<Utc>) -> Self {
    Self {
      data: Arc::new(data),
      fetch_time,
    }
  }

  pub fn new(data: T) -> Self {
    Self::new_at(data, Utc::now())
  }

  pub fn cache_time(&self) -> DateTime<Utc> {
    self.fetch_time
  }
}

impl<T: ?Sized> borrow::Borrow<T> for Cached<T> {
  fn borrow(&self) -> &T {
    &**self
  }
}

impl<T: ?Sized> AsRef<T> for Cached<T> {
  fn as_ref(&self) -> &T {
    &**self
  }
}

impl<T: ?Sized> Clone for Cached<T> {
  fn clone(&self) -> Self {
    Self {
      data: self.data.clone(),
      fetch_time: self.fetch_time,
    }
  }
}

impl<T: ?Sized + fmt::Display> fmt::Display for Cached<T> {
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    fmt::Display::fmt(&**self, f)
  }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for Cached<T> {
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    fmt::Debug::fmt(&**self, f)
  }
}

impl<T: ?Sized> fmt::Pointer for Cached<T> {
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    fmt::Pointer::fmt(&(&**self as *const T), f)
  }
}

impl<T: ?Sized + Hash> Hash for Cached<T> {
  fn hash<H: Hasher>(&self, state: &mut H) {
    (**self).hash(state)
  }
}

impl<T: ?Sized + PartialEq> PartialEq for Cached<T> {
  /// Equality for two `Cached`s.
  ///
  /// Two `Cached`s are equal if their inner values are equal, even if they are
  /// stored in different allocation.
  ///
  /// If `T` also implements `Eq` (implying reflexivity of equality),
  /// two `Cached`s that point to the same allocation are always equal.
  ///
  /// # Examples
  ///
  /// ```
  /// let five = Cached::new(5);
  ///
  /// assert!(five == Cached::new(5));
  /// ```
  #[inline]
  fn eq(&self, other: &Cached<T>) -> bool {
    <T as PartialEq>::eq(&**self, &**other)
  }

  /// Inequality for two `Cached`s.
  ///
  /// Two `Cached`s are unequal if their inner values are unequal.
  ///
  /// If `T` also implements `Eq` (implying reflexivity of equality),
  /// two `Cached`s that point to the same value are never unequal.
  ///
  /// # Examples
  ///
  /// ```
  /// let five = Cached::new(5);
  ///
  /// assert!(five != Cached::new(6));
  /// ```
  #[inline]
  #[allow(clippy::partialeq_ne_impl)]
  fn ne(&self, other: &Cached<T>) -> bool {
    <T as PartialEq>::ne(&**self, &**other)
  }
}

impl<T: ?Sized + PartialOrd> PartialOrd for Cached<T> {
  /// Partial comparison for two `Cached`s.
  ///
  /// The two are compared by calling `partial_cmp()` on their inner values.
  ///
  /// # Examples
  ///
  /// ```
  /// use std::cmp::Ordering;
  ///
  /// let five = Cached::new(5);
  ///
  /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Cached::new(6)));
  /// ```
  fn partial_cmp(&self, other: &Cached<T>) -> Option<Ordering> {
    (**self).partial_cmp(&**other)
  }

  /// Less-than comparison for two `Cached`s.
  ///
  /// The two are compared by calling `<` on their inner values.
  ///
  /// # Examples
  ///
  /// ```
  /// let five = Cached::new(5);
  ///
  /// assert!(five < Cached::new(6));
  /// ```
  fn lt(&self, other: &Cached<T>) -> bool {
    *(*self) < *(*other)
  }

  /// 'Less than or equal to' comparison for two `Cached`s.
  ///
  /// The two are compared by calling `<=` on their inner values.
  ///
  /// # Examples
  ///
  /// ```
  /// let five = Cached::new(5);
  ///
  /// assert!(five <= Cached::new(5));
  /// ```
  fn le(&self, other: &Cached<T>) -> bool {
    *(*self) <= *(*other)
  }

  /// Greater-than comparison for two `Cached`s.
  ///
  /// The two are compared by calling `>` on their inner values.
  ///
  /// # Examples
  ///
  /// ```
  /// let five = Cached::new(5);
  ///
  /// assert!(five > Cached::new(4));
  /// ```
  fn gt(&self, other: &Cached<T>) -> bool {
    *(*self) > *(*other)
  }

  /// 'Greater than or equal to' comparison for two `Cached`s.
  ///
  /// The two are compared by calling `>=` on their inner values.
  ///
  /// # Examples
  ///
  /// ```
  /// let five = Cached::new(5);
  ///
  /// assert!(five >= Cached::new(5));
  /// ```
  fn ge(&self, other: &Cached<T>) -> bool {
    *(*self) >= *(*other)
  }
}

impl<T: ?Sized + Ord> Ord for Cached<T> {
  /// Comparison for two `Cached`s.
  ///
  /// The two are compared by calling `cmp()` on their inner values.
  ///
  /// # Examples
  ///
  /// ```
  /// use std::cmp::Ordering;
  ///
  /// let five = Cached::new(5);
  ///
  /// assert_eq!(Ordering::Less, five.cmp(&Cached::new(6)));
  /// ```
  fn cmp(&self, other: &Cached<T>) -> Ordering {
    (**self).cmp(&**other)
  }
}
impl<T: ?Sized + Eq> Eq for Cached<T> {}

impl<T: ?Sized> Deref for Cached<T> {
  type Target = T;

  #[inline]
  fn deref(&self) -> &T {
    &self.data
  }
}