Skip to main content

not_copy/
lib.rs

1/// This type exists for one purpose and one purpose only. To help you ensure you're mutating
2/// the correct thing, and not mutating a copy. Put `Copy` types in here to rob them of their `Copy` implementation.
3///
4/// This wrapper tries to be transparent in every way, of course it can't implement every trait in existence,
5/// but we'll try to get the important ones. Crate feature "serde" will include `Serialize` and `Deserialize`.
6///
7/// Major omissions from the trait implementations include common math traits, because consuming a `NotCopy`
8/// usually isn't helpful, and those traits consume. However, traits such as `AddAssign` are implemented because
9/// they're just a mutation.
10#[derive(Default, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
11#[repr(transparent)]
12pub struct NotCopy<T>(pub T);
13
14impl<T> From<T> for NotCopy<T>
15{
16    fn from(t: T) -> Self {
17        NotCopy(t.into())
18    }
19}
20
21impl<T, Rhs> std::ops::AddAssign<Rhs> for NotCopy<T>
22where
23    T: std::ops::AddAssign<Rhs>,
24{
25    fn add_assign(&mut self, rhs: Rhs) {
26        self.0 += rhs
27    }
28}
29
30impl<T, Rhs> std::ops::SubAssign<Rhs> for NotCopy<T>
31where
32    T: std::ops::SubAssign<Rhs>,
33{
34    fn sub_assign(&mut self, rhs: Rhs) {
35        self.0 -= rhs
36    }
37}
38
39impl<T, Rhs> std::ops::MulAssign<Rhs> for NotCopy<T>
40where
41    T: std::ops::MulAssign<Rhs>,
42{
43    fn mul_assign(&mut self, rhs: Rhs) {
44        self.0 *= rhs
45    }
46}
47
48impl<T, Rhs> std::ops::DivAssign<Rhs> for NotCopy<T>
49where
50    T: std::ops::DivAssign<Rhs>,
51{
52    fn div_assign(&mut self, rhs: Rhs) {
53        self.0 /= rhs
54    }
55}
56
57impl<T, Rhs> std::ops::RemAssign<Rhs> for NotCopy<T>
58where
59    T: std::ops::RemAssign<Rhs>,
60{
61    fn rem_assign(&mut self, rhs: Rhs) {
62        self.0 %= rhs
63    }
64}
65
66impl<T, Rhs> std::ops::ShlAssign<Rhs> for NotCopy<T>
67where
68    T: std::ops::ShlAssign<Rhs>,
69{
70    fn shl_assign(&mut self, rhs: Rhs) {
71        self.0 <<= rhs
72    }
73}
74
75impl<T, Rhs> std::ops::ShrAssign<Rhs> for NotCopy<T>
76where
77    T: std::ops::ShrAssign<Rhs>,
78{
79    fn shr_assign(&mut self, rhs: Rhs) {
80        self.0 >>= rhs
81    }
82}
83
84impl<T, Rhs> std::ops::BitAndAssign<Rhs> for NotCopy<T>
85where
86    T: std::ops::BitAndAssign<Rhs>,
87{
88    fn bitand_assign(&mut self, rhs: Rhs) {
89        self.0 &= rhs
90    }
91}
92
93impl<T, Rhs> std::ops::BitOrAssign<Rhs> for NotCopy<T>
94where
95    T: std::ops::BitOrAssign<Rhs>,
96{
97    fn bitor_assign(&mut self, rhs: Rhs) {
98        self.0 |= rhs
99    }
100}
101
102impl<T, Rhs> std::ops::BitXorAssign<Rhs> for NotCopy<T>
103where
104    T: std::ops::BitXorAssign<Rhs>,
105{
106    fn bitxor_assign(&mut self, rhs: Rhs) {
107        self.0 ^= rhs
108    }
109}
110
111impl<T, Idx> std::ops::Index<Idx> for NotCopy<T>
112where
113    T: std::ops::Index<Idx>,
114{
115    type Output = T::Output;
116
117    fn index(&self, index: Idx) -> &Self::Output {
118        &self.0[index]
119    }
120}
121
122impl<T, Idx> std::ops::IndexMut<Idx> for NotCopy<T>
123where
124    T: std::ops::IndexMut<Idx>,
125{
126    fn index_mut(&mut self, index: Idx) -> &mut Self::Output {
127        &mut self.0[index]
128    }
129}
130
131impl<T> std::fmt::Display for NotCopy<T>
132where
133    T: std::fmt::Display,
134{
135    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
136        self.0.fmt(f)
137    }
138}
139
140impl<T> std::fmt::Debug for NotCopy<T>
141where
142    T: std::fmt::Debug,
143{
144    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
145        self.0.fmt(f)
146    }
147}
148
149#[cfg(feature = "serde")]
150impl<'de, T> serde::Deserialize<'de> for NotCopy<T>
151where
152    T: serde::Deserialize<'de>,
153{
154    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
155    where
156        D: serde::Deserializer<'de>,
157    {
158        T::deserialize(deserializer).map(NotCopy)
159    }
160}
161
162#[cfg(feature = "serde")]
163impl<T> serde::Serialize for NotCopy<T>
164where
165    T: serde::Serialize,
166{
167    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
168    where
169        S: serde::Serializer,
170    {
171        T::serialize(&self.0, serializer)
172    }
173}