frame_suite/
mutation.rs

1// SPDX-License-Identifier: MPL-2.0
2//
3// Part of Auguth Labs open-source softwares.
4// Built for the Substrate framework.
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at https://mozilla.org/MPL/2.0/.
9//
10// Copyright (c) 2026 Auguth Labs (OPC) Pvt Ltd, India
11
12// ===============================================================================
13// ``````````````````````````````` MUTATION SUITE ````````````````````````````````
14// ===============================================================================
15
16//! Mutation-focused abstractions over owned and borrowed values,
17//! treating mutability as the primary capability rather than ownership.
18
19// ===============================================================================
20// ``````````````````````````````````` IMPORTS ```````````````````````````````````
21// ===============================================================================
22
23// --- Substrate primitives ---
24use sp_runtime::Cow;
25
26// ===============================================================================
27// ````````````````````````````````` MUT-HANDLE ``````````````````````````````````
28// ===============================================================================
29
30/// A mutable access abstraction over a value that may be either borrowed or owned.
31///
32/// `MutHandle` represents the idea that mutation is the primary capability,
33/// while ownership is incidental. It allows code to operate on a value
34/// uniformly without caring whether that value is owned or borrowed.
35///
36/// The key semantic guarantee is:
37/// - mutation is always permitted
38/// - ownership is never implicitly changed or upgraded
39///
40/// This makes it suitable for contexts where:
41/// - mutation must be expressed generically
42/// - ownership should remain explicit and stable
43/// - no hidden allocation or cloning is allowed
44///
45/// Conceptually, it models a "mutable view" over data with a fixed ownership mode,
46/// enabling APIs to focus on behavior (mutation) rather than representation (ownership).
47pub enum MutHandle<'a, T> {
48    Borrowed(&'a mut T),
49    Owned(T),
50}
51
52impl<'a, T> core::ops::Deref for MutHandle<'a, T> {
53    type Target = T;
54
55    fn deref(&self) -> &T {
56        match self {
57            MutHandle::Borrowed(v) => &*v,
58            MutHandle::Owned(v) => v,
59        }
60    }
61}
62
63impl<'a, T> core::ops::DerefMut for MutHandle<'a, T> {
64    fn deref_mut(&mut self) -> &mut T {
65        match self {
66            MutHandle::Borrowed(v) => *v,
67            MutHandle::Owned(v) => v,
68        }
69    }
70}
71
72impl<'a, T> core::convert::AsRef<T> for MutHandle<'a, T> {
73    fn as_ref(&self) -> &T {
74        self
75    }
76}
77
78impl<'a, T> core::convert::AsMut<T> for MutHandle<'a, T> {
79    fn as_mut(&mut self) -> &mut T {
80        self
81    }
82}
83
84impl<'a, T> core::borrow::Borrow<T> for MutHandle<'a, T> {
85    fn borrow(&self) -> &T {
86        self
87    }
88}
89impl<'a, T> core::borrow::BorrowMut<T> for MutHandle<'a, T> {
90    fn borrow_mut(&mut self) -> &mut T {
91        self
92    }
93}
94
95impl<'a, T> From<&'a mut T> for MutHandle<'a, T> {
96    fn from(v: &'a mut T) -> Self {
97        MutHandle::Borrowed(v)
98    }
99}
100
101impl<'a, T> From<T> for MutHandle<'a, T> {
102    fn from(v: T) -> Self {
103        MutHandle::Owned(v)
104    }
105}
106
107impl<'a, T: Clone> From<MutHandle<'a, T>> for Cow<'a, T> {
108    fn from(v: MutHandle<'a, T>) -> Self {
109        match v {
110            MutHandle::Borrowed(v) => Cow::Borrowed(v),
111            MutHandle::Owned(v) => Cow::Owned(v),
112        }
113    }
114}
115
116impl<'a, T: Clone> From<Cow<'a, T>> for MutHandle<'a, T> {
117    fn from(c: Cow<'a, T>) -> Self {
118        match c {
119            Cow::Borrowed(v) => MutHandle::Owned(v.clone()),
120            Cow::Owned(v) => MutHandle::Owned(v),
121        }
122    }
123}
124
125impl<'a, T: core::fmt::Debug> core::fmt::Debug for MutHandle<'a, T> {
126    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
127        core::fmt::Debug::fmt(&**self, f)
128    }
129}
130
131impl<'a, T: Clone> From<&'a T> for MutHandle<'a, T> {
132    fn from(v: &'a T) -> Self {
133        MutHandle::Owned(v.clone())
134    }
135}
136
137impl<'a, T: core::hash::Hash> core::hash::Hash for MutHandle<'a, T> {
138    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
139        (**self).hash(state)
140    }
141}
142
143impl<'a, T: PartialEq> PartialEq for MutHandle<'a, T> {
144    fn eq(&self, other: &Self) -> bool {
145        **self == **other
146    }
147}
148
149impl<'a, T: Eq> Eq for MutHandle<'a, T> {}
150
151impl<'a, T: PartialOrd> PartialOrd for MutHandle<'a, T> {
152    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
153        (**self).partial_cmp(&**other)
154    }
155}
156
157impl<'a, T: Ord> Ord for MutHandle<'a, T> {
158    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
159        (**self).cmp(&**other)
160    }
161}
162
163impl<'a, T: Default> Default for MutHandle<'a, T> {
164    fn default() -> Self {
165        MutHandle::Owned(T::default())
166    }
167}