use ;
use ;
/// A handle to a config entry value which is being watched by a receiver.
///
/// Such handles not only have the semantics of managing a value for a specific field, they also automatically notify the receiver whenever the value changes.
/// A drop guard for modifying data bahind a [`Handle`] using a mutable reference instead of moving in a new value.
///
/// Since `Storage` should notify a receiver whenever data inside of it is modified, it cannot simply hand out mutable references to the value, because that'd allow outside code to implicitly perform a silent storage modification. While ways to do so are also provided, it's heavily discouraged and reserved for special cases.
///
/// The solution to the problem is this struct: `ModificationScope`. It's a drop guard which is created by providing a receiver to the storage. While it has little to no differences to a mutable reference to the data inside in terms of functionality, it notifies the receiver when dropped, ensuring that it will get modified even if a panic or any other kind of early return happens.
///
/// [`Handle`]: struct.Handle.html " "
/////////////////////////////////////////////////
// Trait implementation forwarding for Storage //
/////////////////////////////////////////////////
/*
impl<T: Entry> Clone for Storage<T>
where T::Data: Clone {
#[inline(always)]
fn clone(&self) -> Self {
Self {value: self.value.clone(), _phantom: PhantomData}
}
#[inline(always)]
fn clone_from(&mut self, source: &Self) {
self.value.clone_from(&source.value)
}
}
impl<T: Entry> Copy for Storage<T>
where T::Data: Copy {}
impl<T: Entry> Default for Storage<T>
where T::Data: Default {
#[inline(always)]
fn default() -> Self {
Self {value: Default::default(), _phantom: PhantomData}
}
}
impl<T: Entry> Hash for Storage<T>
where T::Data: Hash {
#[inline(always)]
fn hash<H: Hasher>(&self, state: &mut H) {
self.value.hash(state)
}
}
impl<T: Entry> PartialEq for Storage<T>
where T::Data: PartialEq {
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
// If the underlying type reimplements the != operator
// for performance, we're not gonna intervene.
#[allow(clippy::partialeq_ne_impl)]
fn ne(&self, other: &Self) -> bool {
self.value != other.value
}
}
impl<T: Entry> Eq for Storage<T>
where T::Data: Eq {}
impl<T: Entry> PartialOrd for Storage<T>
where T::Data: PartialOrd {
#[inline(always)]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.value.partial_cmp(&other.value)
}
#[inline(always)]
fn gt(&self, other: &Self) -> bool {
self.value > other.value
}
#[inline(always)]
fn ge(&self, other: &Self) -> bool {
self.value >= other.value
}
#[inline(always)]
fn lt(&self, other: &Self) -> bool {
self.value < other.value
}
#[inline(always)]
fn le(&self, other: &Self) -> bool {
self.value <= other.value
}
}
impl<T: Entry> Ord for Storage<T>
where T::Data: Ord {
#[inline(always)]
fn cmp(&self, other: &Self) -> Ordering {
self.value.cmp(&other.value)
}
}
impl<T: Entry> Add for Storage<T>
where T::Data: Add<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn add(self, rhs: Self) -> Self::Output {
Self {
value: self.value + rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> AddAssign for Storage<T>
where T::Data: AddAssign {
#[inline(always)]
fn add_assign(&mut self, rhs: Self) {
self.value += rhs.value
}
}
impl<T: Entry> Sub for Storage<T>
where T::Data: Sub<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn sub(self, rhs: Self) -> Self::Output {
Self {
value: self.value - rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> SubAssign for Storage<T>
where T::Data: SubAssign {
#[inline(always)]
fn sub_assign(&mut self, rhs: Self) {
self.value -= rhs.value
}
}
impl<T: Entry> Mul for Storage<T>
where T::Data: Mul<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn mul(self, rhs: Self) -> Self::Output {
Self {
value: self.value * rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> MulAssign for Storage<T>
where T::Data: MulAssign {
#[inline(always)]
fn mul_assign(&mut self, rhs: Self) {
self.value *= rhs.value
}
}
impl<T: Entry> Div for Storage<T>
where T::Data: Div<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn div(self, rhs: Self) -> Self::Output {
Self {
value: self.value / rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> DivAssign for Storage<T>
where T::Data: DivAssign {
#[inline(always)]
fn div_assign(&mut self, rhs: Self) {
self.value /= rhs.value
}
}
impl<T: Entry> Rem for Storage<T>
where T::Data: Rem<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn rem(self, rhs: Self) -> Self::Output {
Self {
value: self.value % rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> RemAssign for Storage<T>
where T::Data: RemAssign {
#[inline(always)]
fn rem_assign(&mut self, rhs: Self) {
self.value %= rhs.value
}
}
impl<T: Entry> Neg for Storage<T>
where T::Data: Neg<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn neg(self) -> Self::Output {
Self {value: -self.value, _phantom: PhantomData}
}
}
impl<T: Entry> Shl for Storage<T>
where T::Data: Shl<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn shl(self, rhs: Self) -> Self::Output {
Self {
value: self.value << rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> ShlAssign for Storage<T>
where T::Data: ShlAssign {
#[inline(always)]
fn shl_assign(&mut self, rhs: Self) {
self.value <<= rhs.value
}
}
impl<T: Entry> Shr for Storage<T>
where T::Data: Shr<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn shr(self, rhs: Self) -> Self::Output {
Self {
value: self.value >> rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> ShrAssign for Storage<T>
where T::Data: ShrAssign {
#[inline(always)]
fn shr_assign(&mut self, rhs: Self) {
self.value >>= rhs.value
}
}
impl<T: Entry> BitAnd for Storage<T>
where T::Data: BitAnd<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn bitand(self, rhs: Self) -> Self::Output {
Self {
value: self.value & rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> BitAndAssign for Storage<T>
where T::Data: BitAndAssign {
#[inline(always)]
fn bitand_assign(&mut self, rhs: Self) {
self.value &= rhs.value
}
}
impl<T: Entry> BitOr for Storage<T>
where T::Data: BitOr<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn bitor(self, rhs: Self) -> Self::Output {
Self {
value: self.value | rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> BitOrAssign for Storage<T>
where T::Data: BitOrAssign {
#[inline(always)]
fn bitor_assign(&mut self, rhs: Self) {
self.value |= rhs.value
}
}
impl<T: Entry> BitXor for Storage<T>
where T::Data: BitXor<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn bitxor(self, rhs: Self) -> Self::Output {
Self {
value: self.value ^ rhs.value,
_phantom: PhantomData,
}
}
}
impl<T: Entry> BitXorAssign for Storage<T>
where T::Data: BitXorAssign {
#[inline(always)]
fn bitxor_assign(&mut self, rhs: Self) {
self.value ^= rhs.value
}
}
impl<T: Entry> Not for Storage<T>
where T::Data: Not<Output = T::Data> {
type Output = Self;
#[inline(always)]
fn not(self) -> Self::Output {
Self {value: !self.value, _phantom: PhantomData}
}
}*/