ratio_clone/
traits.rs

1//! # Traits module
2//!
3//! Traits and blanket implementations for borrowing, function applications and comparisons.
4//!
5//! ## License
6//!
7//! This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
8//! If a copy of the MPL was not distributed with this file,
9//! You can obtain one at <https://mozilla.org/MPL/2.0/>.
10//!
11//! **Code examples both in the docstrings and rendered documentation are free to use.**
12
13use std::ops::{Deref, DerefMut};
14
15/// Trait to get a dereference of type T.
16pub trait BorrowDeref<T> {
17    /// Read only borrow.
18    fn borrow(&self) -> impl Deref<Target = T> + '_;
19}
20
21/// Trait to borrow a mutable dereference of type T.
22pub trait BorrowDerefMut<T> {
23    /// Mutably borrow the inner value.
24    fn borrow_mut(&self) -> impl DerefMut<Target = T> + '_;
25}
26
27/// Trait to apply a function to a reference.
28pub trait With<T> {
29    fn with<R>(&self, f: impl FnOnce(&T) -> R) -> R;
30}
31
32impl<T, BD: BorrowDeref<T>> With<T> for BD {
33    fn with<R>(&self, f: impl FnOnce(&T) -> R) -> R {
34        f(self.borrow().deref())
35    }
36}
37
38/// Trait to apply a function to a mutable reference of an internally mutable variable.
39pub trait WithInnerMut<T> {
40    /// Apply a function to mutate this value.
41    fn with_inner_mut<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
42}
43impl<T, BDM: BorrowDerefMut<T>> WithInnerMut<T> for BDM {
44    fn with_inner_mut<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
45        f(self.borrow_mut().deref_mut())
46    }
47}
48
49/// Trait to apply a function to a mutable reference.
50pub trait WithMut<T> {
51    /// Apply a function to this mutable reference.
52    fn with_mut<R>(&mut self, f: impl FnOnce(&mut T) -> R) -> R;
53}
54
55/// Blanket implementation of WithMut for inner mutable types.
56impl<T, WIM: WithInnerMut<T>> WithMut<T> for WIM {
57    fn with_mut<R>(&mut self, f: impl FnOnce(&mut T) -> R) -> R {
58        WithInnerMut::with_inner_mut(self, f)
59    }
60}
61
62/// Inner equality comparison.
63pub trait InnerEq<T> {
64    /// Compare the equality of a wrapped type.
65    fn inner_eq(&self, other: &Self) -> bool;
66}