Skip to main content

no_copy/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3#![deny(clippy::nursery, clippy::pedantic)]
4#![allow(clippy::wildcard_imports, clippy::partialeq_ne_impl)]
5
6use core::{
7    borrow::{Borrow, BorrowMut}, cmp, fmt, hash::{BuildHasher, Hash, Hasher}, iter::{Product, Sum}, ops::{Deref, DerefMut}
8};
9
10mod ops_impl;
11
12#[doc = include_str!("../README.md")]
13#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Default, Clone)]
14#[repr(transparent)]
15pub struct NoCopy<T: ?Sized>(
16    /// Avoid use `x.0` inside the closure, as the closure can capture fields
17    ///
18    /// Trying `*{x}` or `{x}.0`?
19    pub T
20);
21
22impl<T: IntoIterator> IntoIterator for NoCopy<T> {
23    type Item = T::Item;
24    type IntoIter = T::IntoIter;
25
26    #[track_caller]
27    fn into_iter(self) -> Self::IntoIter {
28        self.0.into_iter()
29    }
30}
31
32impl<T: Copy> NoCopy<T> {
33    /// Only from can copy types.
34    ///
35    /// # Examples
36    ///
37    /// ```
38    /// use no_copy::NoCopy;
39    ///
40    /// assert_eq!(NoCopy::from_copy(2), NoCopy(2));
41    /// ```
42    ///
43    /// ```compile_fail
44    /// use no_copy::NoCopy;
45    ///
46    /// let non_copy = String::new();
47    /// let _ = NoCopy::from_copy(non_copy);
48    /// ```
49    pub const fn from_copy(value: T) -> Self {
50        Self(value)
51    }
52}
53
54impl<T: Copy> NoCopy<T> {
55    pub const fn into_inner(this: Self) -> T {
56        this.0
57    }
58}
59
60impl<T: ?Sized + fmt::Write> fmt::Write for NoCopy<T> {
61    #[track_caller]
62    fn write_str(&mut self, s: &str) -> fmt::Result {
63        self.0.write_str(s)
64    }
65
66    #[track_caller]
67    fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
68        self.0.write_fmt(args)
69    }
70
71    #[track_caller]
72    fn write_char(&mut self, c: char) -> fmt::Result {
73        self.0.write_char(c)
74    }
75}
76
77impl<T> From<T> for NoCopy<T> {
78    #[track_caller]
79    fn from(value: T) -> Self {
80        Self(value)
81    }
82}
83impl<T: ?Sized + PartialEq> PartialEq<T> for NoCopy<T> {
84    #[track_caller]
85    fn eq(&self, other: &T) -> bool {
86        self.0.eq(other)
87    }
88
89    #[track_caller]
90    fn ne(&self, other: &T) -> bool {
91        self.0.ne(other)
92    }
93}
94impl<T: ?Sized + PartialOrd> PartialOrd<T> for NoCopy<T> {
95    #[track_caller]
96    fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
97        self.0.partial_cmp(other)
98    }
99
100    #[track_caller]
101    fn lt(&self, other: &T) -> bool {
102        self.0.lt(other)
103    }
104
105    #[track_caller]
106    fn le(&self, other: &T) -> bool {
107        self.0.le(other)
108    }
109
110    #[track_caller]
111    fn gt(&self, other: &T) -> bool {
112        self.0.gt(other)
113    }
114
115    #[track_caller]
116    fn ge(&self, other: &T) -> bool {
117        self.0.ge(other)
118    }
119}
120impl<T: ?Sized> Borrow<T> for NoCopy<T> {
121    #[track_caller]
122    fn borrow(&self) -> &T {
123        self
124    }
125}
126impl<T: ?Sized> BorrowMut<T> for NoCopy<T> {
127    #[track_caller]
128    fn borrow_mut(&mut self) -> &mut T {
129        self
130    }
131}
132impl<U, T: AsRef<U>> AsRef<U> for NoCopy<T> {
133    #[track_caller]
134    fn as_ref(&self) -> &U {
135        self.0.as_ref()
136    }
137}
138impl<U, T: AsMut<U>> AsMut<U> for NoCopy<T> {
139    #[track_caller]
140    fn as_mut(&mut self) -> &mut U {
141        self.0.as_mut()
142    }
143}
144impl<T: ?Sized> Deref for NoCopy<T> {
145    type Target = T;
146
147    #[track_caller]
148    fn deref(&self) -> &Self::Target {
149        &self.0
150    }
151}
152impl<T: ?Sized> DerefMut for NoCopy<T> {
153    #[track_caller]
154    fn deref_mut(&mut self) -> &mut Self::Target {
155        &mut self.0
156    }
157}
158impl<H: ?Sized + Hasher> Hasher for NoCopy<H> {
159    #[track_caller]
160    fn finish(&self) -> u64 {
161        (**self).finish()
162    }
163
164    #[track_caller]
165    fn write(&mut self, bytes: &[u8]) {
166        (**self).write(bytes);
167    }
168
169    #[track_caller]
170    fn write_u8(&mut self, i: u8) {
171        (**self).write_u8(i);
172    }
173
174    #[track_caller]
175    fn write_u16(&mut self, i: u16) {
176        (**self).write_u16(i);
177    }
178
179    #[track_caller]
180    fn write_u32(&mut self, i: u32) {
181        (**self).write_u32(i);
182    }
183
184    #[track_caller]
185    fn write_u64(&mut self, i: u64) {
186        (**self).write_u64(i);
187    }
188
189    #[track_caller]
190    fn write_u128(&mut self, i: u128) {
191        (**self).write_u128(i);
192    }
193
194    #[track_caller]
195    fn write_usize(&mut self, i: usize) {
196        (**self).write_usize(i);
197    }
198
199    #[track_caller]
200    fn write_i8(&mut self, i: i8) {
201        (**self).write_i8(i);
202    }
203
204    #[track_caller]
205    fn write_i16(&mut self, i: i16) {
206        (**self).write_i16(i);
207    }
208
209    #[track_caller]
210    fn write_i32(&mut self, i: i32) {
211        (**self).write_i32(i);
212    }
213
214    #[track_caller]
215    fn write_i64(&mut self, i: i64) {
216        (**self).write_i64(i);
217    }
218
219    #[track_caller]
220    fn write_i128(&mut self, i: i128) {
221        (**self).write_i128(i);
222    }
223
224    #[track_caller]
225    fn write_isize(&mut self, i: isize) {
226        (**self).write_isize(i);
227    }
228}
229impl<H: BuildHasher> BuildHasher for NoCopy<H> {
230    type Hasher = H::Hasher;
231
232    #[track_caller]
233    fn hash_one<T: Hash>(&self, x: T) -> u64
234    where Self: Sized,
235          Self::Hasher: Hasher,
236    {
237        self.0.hash_one(x)
238    }
239
240    #[track_caller]
241    fn build_hasher(&self) -> Self::Hasher {
242        self.0.build_hasher()
243    }
244}
245impl<T: Product<A>, A> Product<A> for NoCopy<T> {
246    #[track_caller]
247    fn product<I: Iterator<Item = A>>(iter: I) -> Self {
248        Self(iter.product())
249    }
250}
251impl<T: Sum<A>, A> Sum<A> for NoCopy<T> {
252    #[track_caller]
253    fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
254        Self(iter.sum())
255    }
256}
257impl<T: Extend<A>, A> Extend<A> for NoCopy<T> {
258    #[track_caller]
259    fn extend<T1: IntoIterator<Item = A>>(&mut self, iter: T1) {
260        self.0.extend(iter);
261    }
262}
263
264macro_rules! impl_fmts {
265    ($trait:ident) => {
266        impl<T: ?Sized + fmt::$trait> fmt::$trait for NoCopy<T> {
267            #[track_caller]
268            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
269                self.0.fmt(f)
270            }
271        }
272    };
273}
274
275impl_fmts!(Binary);
276impl_fmts!(Debug);
277impl_fmts!(Display);
278impl_fmts!(LowerExp);
279impl_fmts!(LowerHex);
280impl_fmts!(Octal);
281impl_fmts!(Pointer);
282impl_fmts!(UpperExp);
283impl_fmts!(UpperHex);