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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use std::cmp::Ordering; use std::fmt::{Display, Formatter, Debug}; use crate::Error; use std::hash::{Hash, Hasher}; #[derive(Debug, Clone, Eq, Ord)] pub enum LimitValue<T> { Limit(T), Limitless, } impl<T: ToString> Hash for LimitValue<T> { fn hash<H: Hasher>(&self, state: &mut H) { match self { LimitValue::Limit(value) => { "Limit".hash(state); value.to_string().hash(state) } LimitValue::Limitless => { "Limitless".hash(state); } } } } impl<T: Default> Default for LimitValue<T> { fn default() -> Self { LimitValue::Limit(T::default()) } } impl<T: PartialEq> PartialEq for LimitValue<T> { fn eq(&self, other: &Self) -> bool { match (self, other) { (LimitValue::Limitless, LimitValue::Limitless) => true, (LimitValue::Limit(value), LimitValue::Limit(other_value)) => value == other_value, _ => false, } } } impl<T: PartialOrd> PartialOrd for LimitValue<T> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { match (self, other) { (LimitValue::Limitless, LimitValue::Limitless) => Some(Ordering::Equal), (LimitValue::Limit(_), LimitValue::Limitless) => Some(Ordering::Greater), (LimitValue::Limitless, LimitValue::Limit(_)) => Some(Ordering::Less), (LimitValue::Limit(value), LimitValue::Limit(other_value)) => value.partial_cmp(other_value), } } } impl<T> From<Option<T>> for LimitValue<T> { fn from(value: Option<T>) -> Self { match value { None => LimitValue::Limitless, Some(v) => LimitValue::Limit(v), } } } impl<T> LimitValue<T> { pub fn is_limit(&self) -> bool { matches!(self, LimitValue::Limit(_)) } pub fn is_limitless(&self) -> bool { matches!(self, LimitValue::Limitless) } pub fn to_value(&self) -> Result<&T, Error> { match self { LimitValue::Limit(a) => Ok(a), LimitValue::Limitless => Err(Error::NotFoundError), } } pub fn to_value_or<'a, TF>(&'a self, default: TF) -> &T where TF: Fn() -> &'a T, { match self { LimitValue::Limit(a) => a, LimitValue::Limitless => default(), } } } impl<T: Display> Display for LimitValue<T> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { LimitValue::Limit(a) => write!(f, "Limit({})", a), LimitValue::Limitless => write!(f, "Limitless"), } } }