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}