use std::{cmp, ops}; use num_traits::Bounded; use serde::{Deserialize, Serialize}; use crate::Semilattice; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] #[serde(transparent)] pub struct Max(T); impl Max { pub fn get(&self) -> &T { &self.0 } pub fn into_inner(self) -> T { self.0 } } impl Max { pub fn incr(&mut self) { self.0 = self.0.saturating_add(&T::one()); } } impl Default for Max where T: Bounded, { fn default() -> Self { Self(T::min_value()) } } impl ops::Deref for Max { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl From for Max { fn from(t: T) -> Self { Self(t) } } impl Semilattice for Max { fn merge(&mut self, other: Self) { if other.0 > self.0 { self.0 = other.0; } } } impl Bounded for Max { fn min_value() -> Self { Self::from(T::min_value()) } fn max_value() -> Self { Self::from(T::max_value()) } } #[allow(clippy::derive_ord_xor_partial_ord)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, Serialize, Deserialize)] #[serde(transparent)] pub struct Min(pub T); impl Default for Min where T: Bounded, { fn default() -> Self { Self(T::max_value()) } } impl ops::Deref for Min { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl From for Min { fn from(t: T) -> Self { Self(t) } } impl cmp::PartialOrd for Min where T: PartialOrd, { fn partial_cmp(&self, other: &Self) -> Option { other.0.partial_cmp(&self.0) } } impl Semilattice for Min { fn merge(&mut self, other: Self) { if other.0 < self.0 { self.0 = other.0; } } } #[cfg(any(test, feature = "test"))] mod arbitrary { use super::*; impl qcheck::Arbitrary for Max { fn arbitrary(g: &mut qcheck::Gen) -> Self { Self::from(T::arbitrary(g)) } } impl qcheck::Arbitrary for Min { fn arbitrary(g: &mut qcheck::Gen) -> Self { Self::from(T::arbitrary(g)) } } }